Programacion-en-Vala.pdf

Share Embed Donate


Short Description

Download Programacion-en-Vala.pdf...

Description

Programaci€n en Vala

PDF generado usando el kit de herramientas de fuente abierta mwlib. Ver http://code.pediapress.com/ para mayor informaci€n. informaci€n. PDF generated at: Sat, 10 Nov 2012 15:34:35 UTC

Contenidos Art€culos Programaci•n en Vala

1

Introducci•n

3

Su primer programa en Vala

4

Conceptos b‚sicos del lenguaje

6

Programaci•n orientada a objetos en Vala

26

Funcionalidades avanzadas del lenguaje

41

Funcionalidades experimentales del lenguaje

63

Bibliotecas del lenguaje

65

Herramientas

66

Otras tƒcnicas

69

Referencias Fuentes y contribuyentes del art€culo

72

Fuentes de imagen, Licencias y contribuyentes

73

Licencias Licencia s de d e art€ ar t€culos culos Licencia

74

Programaci€n en Vala

Programaci€n en Vala Pr€logo Este libro pretende ser un manual de iniciaci€n al lenguaje de programaci€n Vala [1]. Este documento es principalmente una traducci€n del documento original [2], aunque tambi•n aportar‚ material propio.

•ndice 1. Intr Introd oduc ucci ci€n €n 1. ƒQu• ƒQu• es Val Vala? a? 2. ƒA qui•n qui•n va va dirigid dirigidoo este libro libro?? 3. Conven Convencio ciones nes del del lenguaj lenguajee 2. Su prime primerr progra programa ma en Vala Vala 1. Compilado Compilado y ejecuci€ ejecuci€nn del del programa programa 3. Concep Conceptos tos b‚sico b‚sicoss del lenguaj lenguajee 1. 2. 3. 4.

Archivos Archivos de c€digo c€digo y compila compilaci€n ci€n Visi€n Visi€n gene general ral de de la sinta sintaxis xis Come Coment ntar ario ioss Tipo Tiposs de dato datoss

1. Cons Consta tant ntes es 2. Tipo Tiposs b‚si b‚sico coss 3. 3. Cadenas 4. Vecto ectore ress 5. Refe Refere renc ncia iass 6. Conver Conversi€ si€nn est‚tic est‚ticaa de tipos tipos 7. Conversi€n Conversi€n din‚mi din‚mica ca de tipos (Inferencia) (Inferencia) 5. Oper Operad ador ores es 6. Estruct Estructura urass de de cont control rol 1. 1. Bucles 2. Estructuras Estructuras de control control condicionale condicionaless 7. Elemen Elementos tos del lengua lenguaje je 1. 1. M•todos 2. M•to M•todo doss delega delegado doss 3. M•todos M•todos an€nimos an€nimos (Clausura/C (Clausura/Closure) losure) 4. Espa Espaci cios os de nom nombr bres es 5. Estr Estruc uctu tura rass 6. 6. Clases 7. Inte Interf rfac aces es 8. Atribu Atributos tos del c€digo c€digo 4. Programaci€ Programaci€nn orientada orientada a objetos objetos en en Vala Vala 1. 2. 3. 4. 4. 5.

C€di C€digo go b‚sic b‚sicoo Cons Constru truct ctor ores es Destr Destruc ucto tore ress Se„ales Prop Propie ieda dade dess

1

Programaci€n en Vala 6. Heren erenccia 7. Clas Clases es abst abstra ract ctas as 8. Inte Interfa rface ces/ s/Mix Mixin inss 9. Poli Polimo morf rfis ismo mo 10. Informaci€n Informaci€n de tipos tipos en tiempo tiempo de ejecuci€n ejecuci€n 11. Conver Conversi€ si€nn de tipos tipos din‚mic din‚micaa 12. 12. Tipo Tiposs gen• gen•ri rico coss 13. Esquema Esquema de construcci€ construcci€nn tipo tipo GObject GObject 5. Funcionalid Funcionalidades ades avanzadas avanzadas del del lenguaje lenguaje 1. Aserci Asercione oness y Dise„o Dise„o por contra contrato to 2. Mane Manejo jo de de error errores es 3. Direcc Direcci€n i€n de par‚m par‚metr etros os 4. Cole Colecc ccio ione ness 5. M•todo M•todoss con sopor soporte te de sinta sintaxis xis 6. Mult Multih ihil iloo 7. El bucl buclee princ princip ipal al 8. M•to M•todo doss as…n as…ncr cron onos os 9. Refere Referenci ncias as d•bile d•biless 10. Propie Propiedad dad de las las referen referencia ciass 11. Listas de par‚metr par‚metros os de longitud longitud variable variable 12. 12. Pun Puntero teross 13. Clases Clases que no heredan heredan de GLib.Obj GLib.Object ect 6. Funcionalid Funcionalidades ades experim experimental entales es del lenguaje lenguaje 7. Biblio Bibliotec tecas as del del lengua lenguaje je 1. Acceso Acceso a ficheros ficheros en en Vala (biblioteca (biblioteca GIO) 2. Funcionalid Funcionalidad ad de redes redes en Vala Vala (bibliotec (bibliotecaa GIO y SOUP) SOUP) 3. Fich Ficher eros os XML XML en en Vala Vala 4. Prueba Pruebass unitar unitarias ias en en Vala Vala 5. Desarrollo Desarrollo de interfac interfaces es gr‚ficas gr‚ficas de usuario usuario en Vala (Gtk+) (Gtk+) 8. Herra Herrami mien enta tass 1. El compi compilad lador or de Vala Vala (valac (valac)) 2. Las herramie herramientas ntas para para generar generar biblioteca bibliotecass 3. Depura Depuraci€ ci€nn de prog program ramas as 9. Otra Otrass t•c t•cni nica cass 1. Usando Usando toda toda la poten potencia cia de GLib GLib Programaci€n en Vala/Desarrollo

Referencias [1] [1] http http:/  :/   / live.gnome. live.gnome.org/  org/ Vala Vala [2] [2] http http:/  :/   / live.gnome. live.gnome.org/  org/ Vala/  Vala/ Tutorial Tutorial

2

Introducci€n

Introducci€n Introducci€n El lenguaje de programaci€n Vala [1] es un proyecto relativamente nuevo y por ello est‚ sujeto a cambios. Este libro intentar‚ transmitir lo mejor posible cuales son los objetivos que persigue este lenguaje de programaci€n y los convenios que se deben seguir cuando se desarrolla con este lenguaje de programaci€n.

‚Quƒ es Vala? Vala es un nuevo lenguaje de programaci€n [2] que permite usar t•cnicas de programaci€n modernas para desarrollar aplicaciones que se ejecutan usando las bibliotecas de GNOME [3], aunque tambi•n es posible ejecutarlo en otros sistemas operativos y entornos gr‚ficos, debido a sus bajas dependencias (GLib [4] y GObject [5]). Esta plataforma de desarrollo provee de un entorno completo de programaci€n; con funcionalidades como el sistema de tipos din‚micos y el gestor de memoria asistida. Antes de la existencia de Vala, la †nica forma de programar para la plataforma era con la API nativa de C, o utilizando un lenguaje de programaci€n de alto nivel que usan m‚quinas virtuales, como Python o C#, que necesitan un wrapper [6] para usar esa biblioteca. Vala es un lenguaje totalmente diferente de otros lenguajes y otras t•cnicas, ya que el compilador genera c€digo en lenguaje C [7], que puede ser compilado para ser ejecutado sin ninguna biblioteca extra ni wrapper intermedio. Esto tiene una serie de consecuencias, pero entre las mas importantes se encuentran: 1. Los programas escritos en Vala deber…a deber…a tener un desempe„o similar al mismo programa directamente directamente escrito en lenguaje C. Siendo mucho m‚s f‚cil y r‚pido de escribir y mantener. 1. Una aplicaci€n escrita en Vala no puede puede hacer nada que un programa equivalente escrito en lenguaje C no pueda hacer. Sin embargo Vala introduce una serie de funcionalidades que no est‚n disponibles en C, las cuales se mapean en construcciones escritas en C, siendo estas †ltimas dif…ciles y complejas de escribir directamente. Vala es, por lo tanto, un lenguaje de programaci€n moderno con todas las funcionalidades que se puede esperar de una plataforma actual (Python, .NET, etc).

‚A quiƒn va dirigido este libro? Este libro no est‚ pensado para aprender los conceptos de programaci€n b‚sicas (para eso existen libros que puede consultar [8]). Este libro va dirigido a aquellos que quieran aprender a usar este lenguaje de programaci€n y algunas de las bibliotecas que existen para el sistema. Se aconseja conocer alg†n lenguaje de programaci€n y en concreto un lenguaje de programaci€n orientado a objetos. Vala comparte bastante sintaxis con C#, pero algunas otras no se corresponden con construcciones de este lenguaje, por tanto no se entrar‚ en comparaci€n a menos que sea necesario, para evitar que este libro est• enfocado a programadores de C#. Tambi•n ser…a conveniente que el lector tuvieras nociones de C, aunque esto no es necesario en si mismo, es importante darse cuenta que Vala realmente se ejecuta como un programa escrito en C compilado, y puede interactuar con bibliotecas escritas en C. Por tanto un conocimiento de C puede hacer comprender el funcionamiento de Vala.

3

Introducci€n

4

Convenciones del lenguaje El c€digo ir‚ en formato wiki normal al igual que los comandos necesarios para compilar y ejecutar los programas. El c€digo ir‚ acompa„ado de comentarios explicativos siempre que sea necesario para entenderlo.

Referencias [1] [1] [2] [2] [3] [3] [4] [4] [5] [5] [6] [6] [7] [7] [8] [8]

http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Vala_(lenguaje_de_programaci€n) Vala_(lenguaje_de_programaci€n) http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Lenguaje_de_programaci€n Lenguaje_de_programaci€n http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ GNOME GNOME http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ GLib GLib http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ GObject GObject http http:/  :/   / en.wikipedia. en.wikipedia.org/  org/ wiki/  wiki/ Wrapper_library Wrapper_library http http:/  :/   / es.wikibooks. es.wikibooks. org/ wiki/  wiki/ Programaci€n_en_C Programaci€n_en_C http http:/  :/   / es.wikibooks. es.wikibooks. org/ wiki/  wiki/ Fundamentos_de_programaci€n Fundamentos_de_programaci€n

Su primer programa en Vala Su primer programa en Vala Como no puede ser de otro modo el primer programa en Vala va a ser el conocido como "Hola Mundo" que es el programa m‚s simple (sin contar con el programa vac…o) que se puede escribir en un lenguaje de programaci€n. El listado de c€digo ser…a algo como lo que sigue: class Demo.HelloWorld : GLib.Object {  public static int main main( (string string[] [] args) {  

stdout.printf( "Hola, mundo!\n"); stdout.printf("Hola, mundo!\n" );

return 0; } }

A continuaci€n se explicar‚n algunas de las caracter…sticas que contiene el c€digo, para entenderlas es necesario conocer los fundamentos de la programaci€n orientada a objetos [1]. La primera l…nea que se ve es: class Demo.HelloWorld : GLib.Object {

Esta l…nea de c€digo representa la definici€n de una nueva clase [2] llamada HelloWorld. Se puede observar que antes del nombre de la clase se encuentra la palabra "Demo" seguida de un punto. Bien, esto indica el espacio de nombres [3] en el que se mueve el programa. Asimismo, Asi mismo, se puede observar que despu•s del nombre de la nueva clase le siguen dos puntos y la cadena "Glib.Object". Esta cadena va en el mismo formato que la anterior, es decir, "espacio de nombres"."nombre de la clase" e indica una clase de la que hereda [4] la clase anterior. La mayor…a de las nuevas clases heredar‚n de la clase "GLib.Object" que puede ser considerada como la clase b‚sica en el lenguaje Vala, ya que, una parte importante de las funcionalidades del lenguaje est‚n supeditadas a que la clase sobre las que se aplican hereden de esta clase o de una clase descendiente de •sta. Como se ha podido ver la sintaxis de definici€n de una clase es bastante similar a otros lenguajes de programaci€n como C++, Java o C#. Siguiendo con el mismo listado de c€digo tenemos que la siguiente l…nea de c€digo es la que sigue a continuaci€n:  public static int main main( (string string[] [] args) {

Su primer programa en Vala Esta l…nea de c€digo define un m•todo [5] de la clase HelloWorld llamado "main". Este m•todo va precedido por la palabra reservada "public" que indica que se trata de un m•todo p†blico (es decir, puede ser llamado externamente a la clase a la que pertenece). La palabra reservada "static" nos indica que se trata de un m•todo est‚tico (est‚ asociado a la clase y no a un objeto en concreto, es decir, puede ser llamado sin instanciar ning†n objeto de esa clase). Adem‚s se indica que el tipo de datos que devuelve este m•todo es de tipo entero, lo que se hace mediante la palabra reservada "int". Por †ltimo, entre los par•ntesis se indican los par‚metros (los datos que utilizar‚ internamente el m•todo para trabajar). El par‚metro es una lista [6] de cadenas [7] que contendr‚ los par‚metros con los que fu• llamado el programa desde la l…nea de comandos [8]. El hecho de que el m•todo definido se llame "main" no es casual, ya que, Vala considera a este m•todo concreto como el punto de entrada del programa, es decir, que una vez compilado un programa escrito en Vala •ste ser‚ el primer m•todo en ser ejecutado. Este m•todo es el que contiene la correspondientes inicializaciones que requiere el programa que estemos desarrollando, por ejemplo la inicializaci€n de la interfaz gr‚fica de usuario [9]. La siguiente l…nea de c€digo es la que sigue:  

stdout.printf( "Hola, mundo!\n"); stdout.printf("Hola, mundo!\n" );

Esta l…nea de c€digo imprime por la salida est‚ndar (normalmente ser‚ la pantalla del ordenador) el mensaje encerrado entre comillas. Es una llamada al m•todo "printf" del objeto "stdout". En el lenguaje de programaci€n Vala existen una serie de objetos predefinidos a los cuales tenemos acceso por que se encuentran definidos dentro del espacio de nombres GLib que est‚ definido por defecto en cualquier programa Vala. El objeto "stdout" nos permite el acceso a la salida est‚ndar de la m‚quina y entre otros m•todos contiene el m•todo "printf" que muestra un mensaje formateado por dicha salida. La †ltima l…nea importante del c€digo inicial es la siguiente: return 0;

Esta l…nea hace que el programa finalice y devuelva un valor de 0 al sistema. Este valor normalmente se usa para indicar si un programa ha finalizado de forma correcta o no. Si estuviera definido en otro m•todo cualquiera (que no fuera el punto de entrada del programa) devolver…a el valor y se almacenar…a en una variable. Por ejemplo: int valor int  valor = objeto.metodo();

Las †ltimas l…neas del listado †nicamente cierran la definici€n de la clase y el m•todo definido como en cualquier otro lenguaje como por ejemplo C++ o Java.

Compilado y ejecuci€n del programa Una vez que se entiende el funcionamiento del programa, el siguiente paso es compilar dicho programa. Vala al ser un lenguaje de programaci€n compilado [10] y por lo tanto necesita de un compilador [11]. El lenguaje de programaci€n Vala dispone de un compilador llamado "valac" y que es compilador al mismo tiempo del lenguaje de programaci€n Genie [12]. Asumiendo que tenemos el compilador de Vala instalado en nuestra m‚quina, para compilar el primer programa "Hola mundo" suponiendo que est‚ escrito en un fichero llamado "hola.vala" ser…a: valac hola.vala

Esto generar…a un fichero ejecutable llamada "hola" (dependiendo del sistema operativo en el que nos encontremos el fichero binario resultante tendr‚ o no una extensi€n como por ejemplo la ".exe" en Windows). Para ejecutar dicho programa habr‚ que escribir en la l…nea de comandos algo como: ./hola

5

Su primer programa en Vala Y nos mostrar‚ la salida: Hola mundo!

Referencias [1] [1] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Programaci€n_orientada_a_objetos Programaci€n_orientada_a_objetos [2] [2] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Clase_(inform‚tica) Clase_(inform‚tica) [3] [3] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ C%2B%2B#Espacios_de_nombres C%2B%2B#Espacios_de_nombres [4] [4] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Herencia_(programaci€n_orientada_a_objetos) Herencia_(programaci€n_orientada_a_objetos) [5] [5] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ M•todo_(programaci€n_orientad M•todo_(programaci€n_orientada_a_objetos) a_a_objetos) [6] [6] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Lista_(estructura_de_datos) Lista_(estructura_de_datos) [7] [7] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Cadena_(inform‚tica) Cadena_(inform‚tica) [8] [8] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ L…nea_de_comandos L…nea_de_comandos [9] [9] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Interfaz_gr‚fica_de_usuario Interfaz_gr‚fica_de_usuario [10] [10] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Lenguaje_compilado Lenguaje_compilado [11] [11] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Compilador Compilador [12] [12] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Genie_(lenguaje_de_programaci€n) Genie_(lenguaje_de_programaci€n)

Conceptos b„sicos del lenguaje Conceptos b„sicos del lenguaje Archivos de c€digo y compilaci€n Los archivos de c€digo fuente de vala tienen, normalmente, la extensi€n ".vala". El lenguaje de programaci€n Vala no fuerza a que los proyectos tengan una determinada estructura, en cuanto a los paquetes o los nombres de los archivos que contiene una clase, como hacen otros lenguajes como Java. En lugar de eso la estructura se define dentro de los archivos de c€digo mediante texto, definiendo la localizaci€n y estructura l€gica mediante elementos como los espacios de nombres. Cuando se quiere compilar c€digo Vala, se le pasa al compilador una lista de los archivos de c€digo fuente necesarios, y el compilador determina como ensamblarlos todos juntos. La ventaja de todo esto es que se pueden definir tantas clases o funciones como se desee dentro de un †nico archivo de c€digo, incluso combinando distintos espacios de nombres todos dentro del mismo archivo (aunque no se demasiado recomendable por cuestiones de legibilidad y estructura). Vala por lo tanto no exige de manera inherente una determinada estructura para los proyectos que se desarrollan usando esta plataforma. Sin embargo, si existen ciertas convenciones a la hora de estructurar un proyecto desarrollado en Vala. Un buen ejemplo ser…a como se estructura el propio proyecto del compilador de Vala. Todos los archivos de c€digo que pertenezcan al mismo proyecto son suministrados al compilador "valac" mediante la l…nea de comandos, junto con los correspondientes par‚metros de compilaci€n. Esto funciona de forma similar a como se har…a con el c€digo fuente compilado en Java. Por ejemplo: $ valac compiler.vala compiler.vala --pkg libvala

Esa l…nea de c€digo producir…a un archivo binario llamado "compiler" que ser…a enlazado [1] con el paquete "libvala" (cuando nos referimos a paquete lo estamos haciendo a un concepto similar a biblioteca de funciones o la mal traducida librer…a). De hecho, as… es como se genera el compilador de Vala en realidad. Si se quiere que el archivo ejecutable producido tenga un nombre espec…fico (distinto al que el compilador le da) o si se le pasan varios archivos al compilador, es posible especificar el nombre del fichero ejecutable mediante la opci€n "-o":

6

Conceptos b‚sicos del lenguaje $ valac source1.vala source1.vala source2.vala -o myprogram $ ./myprogram

Como se ha comentado anteriormente el compilador de vala es capaz de generar c€digo en lenguaje C en lugar de un archivo ejecutable. As… para realizar esto existe la opci€n "-C" que indicar‚ al compilador que genere todo el c€digo C necesario para crear el ejecutable del proyecto. El compilador crear‚ un archivo con extensi€n ".c" por cada archivo con extensi€n ".vala" que le pasemos. Si abrimos el contenido de esos archivos generados se puede ver el c€digo C equivalente al programa que hemos desarrollado en Vala. Se puede observar como se crean las mismas clases que en Vala pero mediante la biblioteca GObject y c€mo se registran de forma din‚mica en el sistema. Este es un ejemplo del poder que tiene la plataforma de desarrollo de GNOME. Sin embargo, todo esto es a t…tulo informativo, ya que, por suerte no es necesario generar todos estos ficheros, ni entender como funcionan internamente para poder programar en Vala. Si en lugar de generar el fichero de c€digo C s€lo necesitamos generar la cabecera (por ejemplo si estamos generando una biblioteca de funciones ser‚ necesario para poder usarla en C o en otro lenguaje) existe la opci€n "-H" con la que conseguiremos ese objetivo. A continuaci€n un ejemplo que genera los dos ficheros (un fichero de c€digo C y su correspondiente cabecera ".h"): $ valac hello.vala -C -H hello.h

Visi€n general de la sintaxis La sintaxis de Vala est‚ fuertemente inspirada en la sintaxis del lenguaje de programaci€n C#, por lo que la mayor…a de lo explicado aqu… ser‚ muy familiar para los programadores de C# e incluso para los que sepan s epan alg†n lenguaje con un sintaxis similar a C. Independientemente de eso se intentar‚ dar explicaciones breves de los conceptos que se estimen oportunos, aunque no en demasiada profundidad por que no es el cometido del presente documento. Al igual que en otros lenguaje de programaci€n, en Vala existe el concepto de visibilidad o ‚mbito [2] de las variables. Un objeto o referencia †nicamente es v‚lida dentro del ‚mbito definido mediante corchetes ({}) d€nde se defini€ dicho objeto. Estos delimitadores son los mismos que se usan para delimitar las definiciones de las clases, los m•todos, los bloques de c€digos, etc; por lo que todos estos conceptos tienen su propio ‚mbito. Por ejemplo: int funcion1 funcion1 (  (void ) { int a= int  a=0 0; } int funcion2 funcion2 (  (void ) { int a= int  a=1 1;  

stdout.printf( "%d\n", stdout.printf("%d\n" , a); }

El c€digo anterior define dos funciones que tiene sendas variables "a" definidas con distintos valores. La funci€n "funcion2" mostrar‚ el valor de "a", el c†al ser‚ de 1 ya que la variable que se encuentra definida en el ‚mbito de la funci€n "funcion2" vale 1. El lenguaje Vala, a diferencia de otros, no es estricto en la localizaci€n de la definici€n de variables. As… no existe una localizaci€n fija para este prop€sito, si bien es cierto que se aconseja por temas de legibilidad y estructura definirlas al inicio del ‚mbito en el que van a ser usadas. Una variable se define mediante un tipo y un nombre despu•s del tipo. Es decir si queremos definir un entero de nombre edad ser…a algo as…: int edad; int  edad;

En caso de que el tipo fuera una clase (en lugar de un tipo de datos b‚sico) se crea una instancia de una clase. Si se crea una referencia que no se inicia esta no apunta a ning†n objeto. El concepto de referencia aqu… es el mismo que

7

Conceptos b‚sicos del lenguaje en el lenguaje de programaci€n Java, es decir, un puntero [3] que apunta a un objeto. As… para definir un nuevo objeto de una clase se usar‚ el operador new: // Referencia no inicializada Clase objeto; // Referencia inicializada que apunta al nuevo objeto Clase objeto = new Clase();

Comentarios Los comentarios se definen mediante los mismos s…mbolos que en C#, es decir, "//" para los comentarios de 1 l…nea y "/**/" para los comentarios de m‚s l…neas. As… tenemos: // Comentario de una l€nea /* Comentario escrito en m•s de una l€nea */  /* * Comentario especial para sistema de documentaci‚ documentaci‚n n * autom•tica. */ 

En relaci€n al †ltimo tipo de comentarios, el lenguaje de programaci€n Vala dispone de un sistema generador de documentaci€n autom‚tica [4] propio cuyo nombre es Valadoc [5].

Tipos de datos Hablando en general podemos separar los tipos de datos en Vala en dos grandes subgrupos, los tipos de referencia y los de valor. As… estos nombres nos indican la forma en la que estos valores son pasados en el sistema. De esta forma un tipo de valor es copiado en todos los lugares en los que es asignado a otro identificador (otra variable), mientras que un valor de referencia se copia la referencia pero apunta al mismo objeto.

Constantes Las constantes no son propiamente un tipo de dato ya que una constante define un valor de cualquier tipo de dato que no se modifica durante la ejecuci€n del programa. As… una constante se define mediante la palabra reservada "const" seguida del tipo de constante que se define. As… una constante de tipo real se definir…a mediante: const float float PI  PI = 3.1415926 3.1415926; ;

8

Conceptos b‚sicos del lenguaje

Tipos b„sicos Vala dispone de un conjunto amplio de datos b‚sicos entre los que se encuentran los siguientes: ‡ Byte (char, (char, uchar): uchar): Es un valor que que ocupa el m…nimo m…nimo posible posible en memoria memoria (1 byte) byte) y que se utiliza utiliza para almacenar almacenar 1 car‚cter o valores enteros de 0 a 255. ‡ Character Character (unichar): (unichar): Es Es un car‚cter car‚cter de de tipo tipo unicode unicode [6] por lo que ocupar‚ en memoria 2 bytes. ‡ Integer Integer (int, uint): uint): Enteros Enteros positivos positivos que van desde desde 0 a 65536 (o desde desde -32768 a 32767 32767 si es con signo), signo), ocupa ocupa 2 bytes en memoria. ‡ Long Integer Integer (long, (long, ulong): ulong): Es un entero largo largo que ocupa ocupa 4 bytes en memoria memoria y que puede puede representa representarr desde 0 a 4294967296. ‡ Short Integer Integer (short, (short, ushort): ushort): Es un entero que ocupa ocupa 2 bytes bytes en memoria y que que funciona funciona como un Integer. Integer. ‡ Enteros Enteros de tama„o fijo garantiza garantizado: do: Estos tipos garantiz garantizan an que independien independientement tementee de la plataforma plataforma de ejecuci€n ejecuci€n del programa el entero ocupa el mismo tama„o en memoria y tiene por lo tanto los mismos l…mites. Estos tipos de datos son: int8, int16, int32 e int64 (para los enteros con signo) y uint8, uint16, uint32 y uint64 (para los enteros sin signo). ‡ N†meros N†meros de coma flotante: flotante: Hay Hay dos tipos de datos datos de coma flotante flotante,, float y double. double. Los n†meros n†meros float ocupan ocupan en memoria 4 bytes y los double 8 bytes. La principal diferencia es la precisi€n del n†mero. Un n†mero double permite representar n†meros con m‚s precisi€n que un float. ‡ Boolean Boolean (bool): (bool): Tipo de dato boolean booleanoo con dos valores valores posibles posibles cierto cierto (true) y falso falso (false). (false). ‡ Datos compuestos compuestos (struct): (struct): Permite Permite definir definir datos compuestos compuestos mediante mediante la palabra palabra reservada reservada struct. struct. Ejemplo: Ejemplo: struct persona { int edad, String nombre }; ‡ Enumeracion Enumeraciones es (enum): Conjunto Conjunto de valores valores enteros enteros enumerados, enumerados, es decir, decir, salvo que no se indique indique otra cosa se incrementan los valores. Normalmente los valores que se especifican ocupan lo establecida en la lista, sin embargo s€lo se garantiza para los enteros de tama„o fijo garantizado. Para determinar el tama„o en memoria de una variable se usa la palabra reservada "sizeof". Se puede ver el valor m‚ximo y m…nimo que pueden tener un tipo de dato se usan los valores MIN y MAX definidos. Por ejemplo int.MIN y int.MAX.

Cadenas Las cadenas de texto en Vala se definen mediante la palabra reservada string. Estas cadenas son de tipo UTF-8, es decir, son cadenas de texto unicode que pueden representar cualquier texto. string a string  a = "Hola" "Hola"; ;

Adem‚s de este tipo de cadenas existen las cadenas literales, es decir, que no se interpretan los caracteres de escape como "\n". Estas cadenas se definen mediante una triple comillas. Cualquier car‚cter que se encuentre entre el par de tres comillas se inserta dentro de la cadena literal, por ejemplo un tabulador. Ejemplo: string literal string  literal = """Esto es una cadena " literal" literal " y puede contener cualquier car€cter.\n\tTexto tabulado.\n """;

Las cadenas que empiezan mediante una @ son plantillas. Estas plantillas pueden eval†an variables y/o expresiones que est‚n definidas mediante $. Por ejemplo: string plantilla string  plantilla = @"$a * $b = $(a*b)" ; // Devolver• una cadena como "6 * 7 = 42"

Los operadores == y != se utilizan en las cadenas y su comportamiento es distinto a otros lenguajes. As… en Vala los operadores == y != compara el contenido de las cadenas y no la referencias de las mismas. Por ejemplo en Java: C€digo Java

9

Conceptos b‚sicos del lenguaje

10

String a = "hola" "hola"; ; String b = "hola" "hola"; ;

if (a == == b  b) ) { } else { }

C€digo Vala string a string  a = "hola" "hola"; ; string b string  b = "hola" "hola"; ;

if (a == b) { } else { }

El c€digo Java indicar‚ que las variables apuntes a dos objetos distintos (dos referencias distintas) mientras que en Vala si se devolver‚ el valor de cierto ya que ambas cadenas son iguales, aunque se encuentren almacenadas en dos variables distintas. Al igual que en otros lenguajes de programaci€n como Python, las cadenas se pueden partir en partes mediante los operadores [inicio:fin]. As… si queremos seleccionar desde el car‚cter 5 hasta el 9 podemos hacer lo siguiente: string a string  a = "hola mundo"; mundo" ; string b string  b = a[5 a[5:9];

Se puede acceder a un determinado car‚cter mediante los corchetes indicando el …ndice del car‚cter, teniendo en cuenta que los vectores en Vala empiezan en el …ndice 0. string a string  a = "hola mundo"; mundo" ; unichar c = a[0 a[ 0];

Sin embargo esta forma de acceso a las cadenas es de s€lo lectura, es decir, no se puedes escribir un car‚cter (o una cadena) indicando la posici€n en la que debe ser insertado. Por ejemplo el siguiente c€digo es inv‚lido: C€digo INVALIDO en Vala string a string  a = "hola mundo"; mundo" ; a[0 a[0] = "a" "a"; ;

Existen, asimismo, diversos m•todos para poder realizar conversiones entre cadenas y otros tipos de datos b‚sicos y viceversa. A continuaci€n se presentan algunos ejemplos: Ejemplos de conversiones entre cadenas y otros datos b„sicos y viceversa bool b bool  b = "false" "false".to_bool(); .to_bool();

// => false

int i int  i = "-52" "-52".to_int(); .to_int();

// => -52

double d double  d = "6.67428E-11" "6.67428E-11".to_double(); .to_double();

// => 6.67428E-11

string s1 string  s1 = true .to_string();

// => "true"

string s2 string  s2 = 21. 21.to_string(); to_string();

// => "21"

string s3 string  s3 = 24.17 24.17.to_string(); .to_string();

// => "24.170000000000002"

Conceptos b‚sicos del lenguaje

11

Vectores Los vectores se declaran en Vala mediante el tipo de vector (el tipo de dato) seguido de "[]" y un nombre al final. Antes de usar el vector adem‚s de declararlo lo debemos inicializar indicando el tama„o del mismo o en su caso los valores que lo componen. Por ejemplo si queremos declarar un vector de 100 n†meros enteros llamado "lista_primos" ser…a algo as…: int[] int [] lista_primos = new int int[ [100 100]; ]; // Para saber el tamaƒo de un vector se usa la propiedad "length"   stdout.printf("%d\n" stdout.printf( "%d\n", , lista_primos.length);

Al igual que con las cadenas, los vectores tambi•n pueden ser divididos en varias partes usando los operadores "[]". As… teniendo definido un vector de enteros tal que "{ 2, 4, 6, 8 }" podemos trocearlo de la siguiente forma: int[] int [] lista = { 2, 4, 6, 8 }; int[] int [] c = lista[ 1:3];

// => { 4, 6 }

El nuevo vector es un vector completamente independiente del original y los cambios realizados sobre el segundo no afectan al primero. Adem‚s de vectores se pueden definir matrices multidimensionales posicionando una coma (o m‚s dependiendo del n†mero de dimensiones que se quiera) dentro de los corchetes. As… por ejemplo para definir una matriz bidimensional vac…a de 3x3 se realizar…a de la siguiente forma: int[,] int [,] c = new int int[ [3,3]; // Si se quiere una matriz con los valores s‚lo tenemos que indicarlos despu•s del = int[,] int [,] d = {{2 {{ 2, 4, 6}, {3, 5, 7}, {1, 3, 5}};

Este tipo de matrices se representa internamente en memoria como un bloque contiguo. Los vectores de vectores "[][]" en los cuales cada fila tiene un tama„o distinto no est‚n soportados a†n. Se pueden a„adir elementos al vector mediante el uso del operado "+=". Sin embargo, esto s€lo funciona para vectores definidos como locales o privados. El vector ser‚ redimensionado en caso de ser necesario. En caso de que esto pase, internamente se incrementa en potencias de 2 por temas de eficiencia y velocidad. Sin embargo la propiedad ".length" indicar‚ el n†mero actual de elementos y no el valor interno. Por ejemplo: int[] int [] e = {} e += 12 12; ; // Ahora e tiene un tamaƒo interno de 2 (Aunque la propiedad   length vale 1) e += 5;

// Ahora e tiene un tamaƒo interno de 2 (La propiedad length

 vale 2) e += 37 37; ; // Se aƒade otro elemento y se vuelve a redimensionar internamente. Ahora su tama‚o interno sera de

4 elementos (La propiedad

 length valdr€ 3)

Si despu•s de los par•ntesis despu•s del identificador junto con un tama„o se obtendr‚ un vector de tama„o fijo. Este tipo de vectores se aloja en memoria en la pila [7] o mediante "in-line allocated" (si se usa como variable de una clase y no puede ser redimensionado despu•s. Ejemplo:

Conceptos b‚sicos del lenguaje

12

int e[ int  e[10 10]; ]; // No necesita new. No se le pueden aƒadir m•s elementos.

Vala no realiza comprobaciones de l…mites en el acceso a los vectores en tiempo de ejecuci€n. Si se necesita m‚s seguridad sobre esta tem‚tica se recomienda el uso de estructuras de datos m‚s sofisticadas como por ejemplo los "ArrayList". M‚s adelante se tratar‚n m‚s en profundidad esta familia de estructuras de datos (colecciones, lista, etc). As… por ejemplo en el siguiente ejemplo se accede a una posici€n inexistente del vector; en lugar de mostrarnos un error mostrar‚ el contenido de una posici€n de memoria externa al vector y de contenido indeterminado (basura): int[] int [] vector = new int int[ [10 10]; ];   stdout.printf("%d\n" stdout.printf( "%d\n", , vector[300 vector[ 300]); ]); // Puede mostrar cualquier valor,  pero no mostrar€ errores

Referencias El tipo de dato conocido como referencia [8] es un tipo de dato que contiene un valor que permite el acceso indirecto al contenido de una variable. El termino referencia es muy similar al termino puntero que se usa en otros lenguajes de programaci€n como C, sin embargo en este caso una referencia normalmente se usar‚ para los objetos creados, mientras que un puntero puede ser de cualquier tipo de variable (entero, coma flotante, cadena, etc). As… cada vez que dentro de un programa escrito en Vala pasemos un objeto a una funci€n o m•todo de otra clase, en realidad estar…amos pasando una referencia. El sistema es capaz de tener un registro de cuantas referencias siguen en uso, con el fin de que pueda realizar la gesti€n de memoria por nosotros. Entre otras cosas el sistema de gesti€n de memoria de Vala se encarga de liberar la memoria que ocupa un objeto cuando todas las referencias que apuntan a •l hayan dejado de usarse. El valor de una referencia que no apunte a ninguna parte ser‚ null. M‚s informaci€n acerca de las referencias en el cap…tulo de Programaci€n orientada a objetos en Vala [9].

Conversi€n est„tica de tipos Cuando nos encontramos desarrollando un programa en cualquier lenguaje de programaci€n fuertemente tipado [10], normalmente nos encontramos ante el problema de pasar de un tipo de datos a otro con bastante frecuencia. En una conversi€n de datos est‚tica el compilador sabe cuales son los tipos de datos origen y destino antes de ejecutar el programa compilado. As… en Vala se puede realizar este tipo de conversi€n de datos estableciendo el tipo de datos entre par•ntesis despu•s de una igualdad. En una conversi€n est‚tica de datos no se establece ning†n tipo de comprobaci€n de seguridad. Este tipo de conversiones son v‚lidas para todos los tipos de datos en Vala. Por ejemplo: int i int  i = 10 10; ; float j float  j = (float (float) ) i;

Conversi€n din„mica de tipos (Inferencia) Existe otro tipo de conversi€n de tipos de datos conocida como conversi€n din‚mica o inferencia de tipos [11] que se usa sobre todo en lenguajes de programaci€n funcionales [12]. As… dado que Vala permite definir variables sin tipo inicial usando para ello la palabra reservada var, var, es necesario que se pueda establecer el tipo de una variable con posterioridad a su definici€n, es decir, inferir ese tipo a partir de una expresi€n que se encuentra a la derecha de una igualdad. Por ejemplo el siguiente c€digo ser…a legal en Vala: var p = new Person();

// es lo mismo que: Person p = new Person();

var s = "hello" "hello"; ;

// es lo mismo que: string s = "hello";

var l = new List(); // es lo mismo que: List l = new List(); var i = 10 10; ;

// es lo mismo que: int i = 10;

Conceptos b‚sicos del lenguaje Este tipo de variables sin tipo s€lo est‚n permitidas como variables locales [13]. Este mecanismo es muy †til para usar en los par‚metros de los m•todos gen•ricos.

Operadores Como otros lenguajes de programaci€n, Vala tiene a disposici€n de los programadores una gran variedad de operadores para usar con distintos prop€sitos. Podemos separar los operadores de Vala en varios tipos seg†n el tipo de datos sobre el que operan.

Operadores aritmƒticos Estos operadores se aplican a todos los tipos num•ricos definidos anteriormente. Estos operadores son los que aparecen en la siguiente tabla:

Operadores aritmƒticos I (identificador = expresi€nA OPERADOR expresi€nB) Operad Operador or Descri Descripci pci€n €n =

El oper operado adorr de asigna asignaci€ ci€nn se utiliz utilizaa para para real realiza izarr asign asignaci acion ones es entr entree una una varia variable ble y el result resultado ado de una una expr expresi esi€n €n o un valo valorr (otra (otra variable). A la izquierda de este operador debe aparecer un identificador (una variable) y a la derecha del mismo puede aparecer un valor, una expresi€n o otra variable.

+

El oper operado adorr de suma suma reali realiza za la la adici adici€n €n de las las expres expresion iones es que que tiene tiene a su izquie izquierda rda y a su dere derecha cha.. Este Este oper operado adorr es aplica aplicable ble a las las cadenas de texto ("string").

-

El ope opera rado dorr de res resta ta rea reali liza za la la rest restaa de la exp expre resi si€n €n que que tie tiene ne a la la dere derech chaa sobr sobree la expr expres esi€ i€nn que que tien tienee a su izqu izquie ierd rda. a.

*

El ope opera rado dorr de mul multi tipl plic icac aci€ i€nn real realiz izaa el pro produ duct ctoo entr entree la exp expre resi si€n €n que que tie tiene ne a su izq izqui uier erda da y a su dere derech cha. a.

 /

El operador de divisi€n divisi€n realiza esta operaci€n usando usando como dividendo dividendo la expresi€n que que tiene a su izquierda y como como divisor la expresi€n expresi€n que tiene a su derecha.

%

El oper operado adorr de m€du m€dulo lo calc calcula ula el resto resto de una una divi divisi€ si€nn siend siendoo la expr expresi esi€n €n que que tien tienee a su izqu izquier ierda da el el cocie cociente nte y la exp expres resi€n i€n que existe existe a su derecha el divisor.

Operadores aritmƒticos II (identificador OPERADOR expresi€n) Operad Operador or Descri Descripci pci€n €n +=

Este Este oper operado adorr reali realiza za la la adici adici€n €n de la la expre expresi€ si€nn sobr sobree el conten contenido ido que tenga tenga el iden identif tifica icador dor a su izquie izquierda rda..

-=

Este Este oper operado adorr real realiza iza la resta resta de la expres expresi€n i€n sobre sobre el conten contenido ido que tenga tenga el identi identific ficado adorr a su izquie izquierda rda..

*=

Este Este opera operador dor realiz realizaa el prod product uctoo entre entre el el conte contenid nidoo del del ident identifi ificad cador or a su su izqu izquier ierda da y la la expre expresi€ si€nn a su derech derecha. a. El result resultado ado se almacena en el identificador.

 /=

Este operador realiza la divisi€n divisi€n tomando como como dividendo el contenido contenido del identificador identificador y como divisor divisor el resultado de la expresi€n expresi€n de la derecha. El resultado de la divisi€n se almacena en el identificador.

%=

Este Este operad operador or calcu calcula la el m€dul m€duloo (resto) (resto) de de la divisi divisi€n €n,, tomand tomandoo como como divide dividendo ndo el el conten contenido ido del del ident identifi ificad cador or y como como divis divisor or el resultado de la expresi€n de la derecha. El resultado de la divisi€n se almacena en el identificador.

13

Conceptos b‚sicos del lenguaje

14

Operadores aritmƒticos III (identificador OPERADOR  o bien OPERADOR identificador) Opera Operador dor Descri Descripci pci€n €n ++

Este Este oper operad ador or incr increm emen enta ta en uno uno el el con conte teni nido do del del iide dent ntif ific icad ador or..

--

Este Este oper operad ador or decr decrem emen enta ta en uno uno el cont conten enid idoo del del iden identi tifi fica cado dor. r.

Los operadores "++" y "--" se pueden usar tanto en una posici€n prefija al identificador como postfija al mismo. Sin embargo existe una sutil diferencia entre ambos usos. Supongamos que tenemos este operador en una expresi€n (variable++ o ++variable). As…, si el operador est‚ delante del identificador la expresi€n devolver‚ el nuevo valor (variable + 1) sin embargo, si tenemos el operador detr‚s del identificador entonces la expresi€n devolver‚ el valor antiguo (variable). Esto puede hacer que cometamos errores dif…ciles de detectar. Por ejemplo: C€digo con operador prefijo int a int  a = 0; int b int  b = ++a; // Aqu€ b valdr€a 1 que ser€a el valor que devuelve la expresiƒn

C€digo con operador postfijo int a int  a = 0; int b int  b = a++; // Aqu€ b valdr€a 0 que ser€a el valor que devuelve la expresiƒn

Operadores a nivel de bits Un operador a nivel de bits es aquel que realiza una operaci€n sobre los bits que componen los par‚metros que recibe. Los operadores booleanos que se definen en Vala son los mismos que se definen en el ‚lgebra de Boole [14] o compuestos por varios b‚sicos. As… tendremos los siguientes operadores:

Operadores a nivel de bits I (expresi€n_booleana_A (expresi€n_booleana_A OPERADOR_BOOLEANO expresi€n_booleana_B) Operad Operador or Descri Descripci pci€n €n |

Este operador realiza la operaci€n booleana OR de la expresi€n que tiene a su izquierda y la expresi€n que tiene a su derecha.

^

Este op operador re realiza la la op operaci€n booleana XOR de la expresi€n que tiene a su izquierda y la expresi€n que tiene a su derecha.

&

Este operador realiza la operac raci€n booleana AND de la expresi€n que tiene a su izquierda y la expresi€n que tiene a su derecha.

Conceptos b‚sicos del lenguaje

15

Operadores a nivel de bits II (OPERADOR_BOOLEANO expresi€n_booleana) expresi€n_booleana) Operad Operador or Descri Descripci pci€n €n ~

Este op operador re realiza la la op operaci€n bo booleana NOT de la expresi€n que tiene a su derecha.

Operadores a nivel de bits III (identificador OPERADOR_BOOLEANO expresi€n expresi€n booleana) Operad Operador or Descri Descripci pci€n €n |=

Este operador realiza la operaci€n booleana OR entre el identificador y el resultado de la expresi€n booleana. El resultado se almacena dentro del identificador.

^=

Este op operador re realiza la la op operaci€n bo booleana XOR entre el identificador y el resultado de la expresi€n booleana. El resultado se almacena dentro del identificador.

&=

Este Este operad eradoor real realiz izaa la operac eraci€ i€nn boole oolean anaa AND entre el identificador y el resultado de la expresi€n booleana. El resultado se almacena dentro del identificador.

Operadores a nivel de bits IV (identificador OPERADOR_BOOLEANO OPERADOR_BOOLEANO expresi€n entera) Operad Operador or Descri Descripci pci€n €n >>

Este Este opera operador dor realiz realizaa el movi movimie miento nto de los los bits bits de de izquie izquierda rda a derech derechaa un n†m n†mero ero de de veces veces igu igual al al valor valor devu devuelt eltoo por por la expre expresi€ si€nn entera. Se introducir‚n tantos 0 por la izquierda como indique la expresi€n entera.

>=

Este operador operador realiza realiza el movi movimient mientoo de los bits de izquie izquierda rda a derecha derecha un un n†mero n†mero de veces veces igual igual al valor devuelto devuelto por la expresi expresi€n €n entera. Se introducir‚n tantos 0 por la izquierda como indique la expresi€n entera. El resultado se almacena en el identificador.

{  

stdout.printf( "age has changed\n"); stdout.printf("age changed\n" );

});

N€tese que este caso se debe usar la representaci€n del nombre de la propiedad d€nde los guiones bajos se reemplazan por guiones: nombre_propiedad pasa a ser nombre-propiedad en esta representaci€n, la cual es el convenio de nombres de propiedades usado por GObject. Las notificaciones se pueden deshabilitar mediante el atributo de c€digo CCode justo CCode  justo antes de la declaraci€n de la propiedad:  public class  MyObject : Object { [CCode(notify [CCode(notif y = false)] // En esta propiedad no se emite la seƒal

 public int int without_notification  without_notification { get; set; } // Aqu€ si se emite la seƒal.

 public int int with_notification  with_notification { get; set; } }

Existe otro tipo de propiedades que se llaman propiedades de constructor que se describen m‚s adelante en la secci€n Esquema de construcci€n tipo GObject.

32

Programaci€n orientada a objetos en Vala

Herencia En Vala una clase puede derivarse (y heredar) de cero o una clase. En la pr‚ctica la mayor…a de las veces heredar‚ de una clase, puesto que no hay herenc…a impl…cita como en otros lenguajes de programaci€n. Cuando se define una clase nueva que hereda de otra, se crea una relaci€n entre las clases d€nde las instancias de la subclase definida son a su vez intancias de la clase padre. Esto significa que la operaci€n sobre s obre instancias de las clase padre tambi•n se pueden aplicar sobre las instancias de la clase hija. De hecho, d€nde se debe usar una instancia de la clase padre, se podr‚ sustituir por una instacia de la clase hija. Cuande se escribe la definici€n de una clase es posible definir de forma exacta quien va a poder acceder a los m•todos y a los datos del objetos. El siguiente ejemplo demostrar‚ la variedad de estas opciones: class SuperClass  : GLib.Object {  private int int data;  data;  public SuperClass (int int data)  data) { this.data = data; }

 protected  void  protected_method () { }

 public static void  public_static_method () { } }

class SubClass  : SuperClass {  public SubClass SubClass() () {  base(10 10); ); } }

El miembro dato data de la clase SuperClass es una instancia de datos de esa clase. Habr‚ un miembro de ese tipo en cada una de las instancias de la clase padre SuperClass, SuperClass, y puesto que ha sido declarada como privada ( private) private) s€lo puede ser accedida por el c€digo que forma parte de la definici€n de la clase padre. El m•todo protected_method es un m•todo de SuperClass. SuperClass. Este m•todo al haber sido definido como protegido (protected) protected) podr‚ ser ejecutado por la clase SuperClass y por todas las clases descendientes de •sta. El m•todo public_static_method tiene dos modificadores. El modificador static significa que puede ser ejecutado sin necesidad de crear una instancia de la clase o de alguna clase hija de •sta. Como resultado de esto, este m•todo no tendr‚ acceso a la referencia cuando se ejecute. El modificado public significa que el m•todo puede ser llamado desde cualquier parte del c€digo, sin importar la relaci€n que tenga con la clase padre o sus derivadas. Dadas estas definicioes, cualquier instancia de la clase SubClass tendr‚ los tres miembros de la clase padre SuperClass, SuperClass, pero s€lo podr‚ acceder a los miembros no privados ( private). private). El c€digo externo a la clase hija s€lo podr‚ acceder a los miembros que hayan sido definidos como p†blicos ( public). public). Con el identificador base se puede enlazar con el contructor de la clase base, en caso de que sea necesario inicializar algunos datos a los que s€lo tenemos acceso mediante el constructor de la clase padre.

33

Programaci€n orientada a objetos en Vala

Clases abstractas Hay otro modificador para los m•todos, denomidado abstract. abstract. Este modificador permite definir un m•todo que no tiene implementaci€n en la clase d€nde se define. En lugar de implementarse en la clase d€nde es definido, se obliga a que sean las clases hijas de esa las que definan ese m•todo antes de que puede ser llamado. Esto permite definir operaciones que se pueden ejecutar en todas las instancias de un tipo, mientras que nos aseguramos de que todos los tipos definen sus propias implementaciones de esa funcionalidad. Una clase que contiene m•todos abstractos debe ser definida como una clase abstracta tambi•n. El resultado de esto es que no se permitir‚ crear instancias de esa clase. Ejemplo:  public abstract class  Animal : Object {  public void  eat eat() () {  

stdout.printf( "*chomp chomp*\n"); stdout.printf("*chomp chomp*\n" ); }

 public abstract void  say_hello(); say_hello(); }

 public class Tiger : Animal {  public override void  say_hello say_hello() () {  

stdout.printf( "*roar*\n" ); stdout.printf("*roar*\n" }

}

 public class Duck : Animal {  public override void  say_hello say_hello() () {  

stdout.printf( "*quack*\n" ); stdout.printf("*quack*\n" }

}

La implementaci€n de un m•todo abstracto debe ser marcada con el modificador override. override. Como se ve en el ejemplo se define una clase abstracta denomida Animal. Animal. Esta clase define dos m•todos, uno de ellos normal que denomina eat y define como come un animal (se supone que todos comen igual); el otro m•todo say_hello define como un animal dice hola, y se define como abstracto para que en cada clase que defina un animal tenga una implementaci€n distinta. As… tenemos una clase Tiger que representa a un tigre y dice hola escribiendo "*roar*", y por otra parte tenemos la clase Duck que hereda tambi•n de Animal y que representa a un pato y que implementa say_hello escribiendo "*quack*". Como se puede adivinar este mecanismo es muy †til para definir una interfaz com†n para una familia de clases que heredan de la clase abstracta y que no puede ser instanciada.

34

Programaci€n orientada a objetos en Vala

Interfaces/Mixins Una clase Vala puede implementar un n†mero arbitrario de interfaces. Cada una de ellas es un tipo, parecido a una clase, aunque no puede ser instanciada. Cuando una clase implementa una interfaz, una instancia de una clase as…  declarada tambi•n es una instancia de la interfaz, y por lo tanto puede ser usada en sustituci€n d€nde se espere una instancia de la interfaz. El procedimiento para implementar una interfaz es el mismo que para heredar de una clase abstracta. Una interfaz simple puede ser como sigue:  public interface  ITest : GLib.Object {  public abstract int int data_1  data_1 { get; set; }  public abstract void  method_1 method_1(); (); }

Este c€digo define una interfaz llamada ITest el cual requiere la clase GLib.Object como padre y contiene dos miembros. El miembro data_1 es una propiedad que ha sido declarado como abstracto. Esto no quiere decir que la interfaz albergue una propiedad realmente, sino que obliga a cualquier clase que implemente esta interfaz a que contenga un miembro propiedad del mismo tipo y con el mismo nombre y que contenga asimismo los bloques get y set. set. Es necesario que se defina como abstracto puesto que una interfaz no puede tener ning†n miembro dato definido. El segundo miembro de la interfaz se denomina method_1 y es un m•todo. Este m•todo a estar definido como abstracto debe ser definido por la clase que implemente esta interfaz. La forma m‚s simple para una implementaci€n completa de una interfaz es:  public class Test1 : GLib.Object, ITest {  public int int data_1  data_1 { get; set; }  public void  method_1 method_1() () { } }

Y puede ser usado de la siguiente forma: var t = new Test1(); t.method_1(); ITest i = t; i.method_1();

En el c€digo se puede apreciar que se define un objeto de tipo Test1 que implementa la interfaz ITes. ITes. Se define as…  una referencia de tipo ITets y la asignamos para que apunte al nuevo objeto de tipo Test1. Test1. Como hemos dicho se podr‚n acceder a los m•todos que define la interfaz y que obliga a que sean implementados en la clase. Hay que recalcar que no se crea una instancia de la interfaz (el c€digo var i = new ITest(); NO ES CORRECTO), CORRECTO), sino que se crea una referencia de la interfaz que no se inicializa y se usa para asignarla al nuevo objeto creado. Las interfaces en Vala no puede heredar de otras interfaces, pero puede declarar como prerrequisito a otras interfaces, lo cual en la pr‚ctica funciona de la misma forma. Por ejemplo, ser…a deseable que cualquier clase que implementara la interfaz List tambi•n debiera implementar la interfaz Collection. Collection. La sintaxis para realizar esto es la misma que la que permite definir las interfaces que implementa una clase:  public interface  List : Collection { // Esto obligar• a que la clase que implemente la interfaz "List" "List" deba  deba implementar la interfaz "Collection" tambi•n "Collection"  tambi•n }

35

Programaci€n orientada a objetos en Vala Esta definici€n de List no puede ser implementada sin que se implemente la interfaz Collection tambi•n, y Vala obliga a que se especifique todas las interfaces que deben ser implementadas para aquellas clases que quieran implementar la interfaz List. List. El siguiente c€digo muestra un ejemplo:  public class ListClass : GLib.Object, Collection, List { }

Las interfaces de Vala pueden tener una clase como prerrequisito tambi•n, si el nombre de una clase se define en los prerrequisitos de una interfaz entonces, la interfaz s€lo puede ser implementada en clases derivadas de la clase que se se especific€. Esto es †til para asegurar que una instancia de una interfaz es tambi•n una clase derivada de la clase GLib.Object, GLib.Object, y por lo tanto la interfaz puede ser usada, por ejemplo, como el tipo de una propiedad. El hecho de que una interfaz no pueda ser heredada de otra interfaz es s€lo una distinci€n t•cnica, ya que, en la pr‚ctica el sistema de Vala funciona igual al de otros lenguajes en este ‚rea, pero con la funcionalidad extra de los prerrequisitos de las clases. Hay otra diferencia importante entre las interfaces en Vala y las interfaces Java/C#: las interfaces en Vala puede tener m•todos que no sean abstractos. De hecho Vala permite la implementaci€n de m•todos en las interfaces. Debido a esto, las interfaces de Vala pueden actuar como Mixins [30]. Esto es una forma de restricci€n de la herencia m†ltiple.

Polimorfismo El polimorfismo [11] describe la forma en la cual el mismo objeto puede ser usado como m‚s de un tipo de cosa. Varias de las t•cnicas ya descritas aqu… sugieren c€mo es posible esto en Vala: una instancia de una clase puede ser usada como una instancia de una clase padre, o de cualquier implementaci€n de las interfaces, sin cualquier conocimiento de su tipo actual. A continuaci€n se muestra un ejemplo: class SuperClass  : GLib.Object {  public void  method_1 method_1() () {  

stdout.printf( "SuperClass.method_1()\n" ); stdout.printf("SuperClass.method_1()\n" }

}

class SubClass  : SuperClass {  public void  method_1 method_1() () {  

stdout.printf( "SubClass.method_1()\n" ); stdout.printf("SubClass.method_1()\n" }

}

Estas dos clases implementan un m•todo llamado method_1, method_1, y la clase SubClass contiene por tanto dos m•todos llamados method_1, method_1, uno heredado de SuperClass y otro propio. Cada uno de ellos se ejecuta como muestra el siguiente c€digo: SubClass o1 = new SubClass(); o1.method_1(); SuperClass o2 = o1; o2.method_1();

Este c€digo llamar‚ a los dos m•todos. La segunda l…nea contiene la inicializaci€n de la clase SubClass y llamar‚ a la versi€n de esa clase del m•todo. La cuarta l…nea contiene la inicializaci€n de una instancia o2 de la clase SuperClass y ejecutar‚ la versi€n del m•todo de esta clase.

36

Programaci€n orientada a objetos en Vala El problema que muestra el c€digo, es que cualquiera que sea el c€digo si contiene una instancia de la clase SuperClass, SuperClass, •sta ejecutar‚ el m•todo que se define en esa clase, independientemente de a que objeto apunte esa referencia. Para cambiar ese comportamiento es usar los m•todos virtuales. El siguiente c€digo muestra una versi€n modificada del ejemplo anterior usando los m•todos virtuales: class SuperClass  : GLib.Object {  public virtual void  method_1 method_1() () {  

stdout.printf( "SuperClass.method_1()\n" ); stdout.printf("SuperClass.method_1()\n" }

}

class SubClass  : SuperClass {  public override void  method_1 method_1() () {  

stdout.printf( "SubClass.method_1()\n" ); stdout.printf("SubClass.method_1()\n" }

}

Cuando este c€digo se use de la misma forma que el anterior, el m•todo method_1 de la clase SubClass ser‚ el ejecutado, en lugar del m•todo de la clase padre. Esto es debido a que le hemos indicado al sistema que el m•todo method_1 es un m•todo virtual, lo cual significa que si es redefinido en una clase hija, ser‚ esa nueva versi€n la se ejecutar‚ siempre en instancias de esa clase hija, independientemente del tipo y conocimientos de la instancia que lo ejecute. Esta distinci€n puede que sea familiar a los programadores de algunos lenguajes, como C++, pero es totalmente diferente al estilo del lenguaje Java, en d€nde se previene del uso de los m•todos virtuales. El lector puede que se haya dado cuenta de que cuando un m•todo se declara como abstracto ( abstract) abstract) debe ser virtual tambi•n. De lo contrario, no ser…a posible ejecutar ese m•todo dada una instancia del tipo aparente en el cual fue definido. Cuando se implementa un m•todo abstracto en una subclase, se puede elegir declararlo como sobreescribible (overriden (overriden), ), estableciendo la naturaleza virtual de ese m•todo, y permitiendo a los subtipos que usen la misma implementaci€n si lo desean. Es posible implementar los m•todos de una interfaz de tal forma que las subclases puedan cambiar la implementaci€n. El proceso en este caso es declarar la implementaci€n inicial como virtual, y de ese modo las subclases pueden sobrescribir si as… lo necesitan. Cuando se escribe una clase, es muy com†n querer usar la funcionalidad definida en la clase de la cual hereda. Esto es complicado en los lugares d€nde se usa el nombre del m•todo m‚s de una vez en el ‚rbol de herencia de las clases. Para este cometido Vala tiene la palabra reservada base. base. El caso m‚s com†n para usar este mecanismo es cuando se ha sobrescrito la funcionalidad de un m•todo virtual para suministrar funcionalidad extra, pero aun se necesita la funcionalidad del m•todo de la clase padre. El siguiente ejemplo muestra como actuar en este caso:  public override void  method_name method_name() () {  base.method_name();  

extra_task();

}

El c€digo muestra como se ejecuta el m•todo de la clase padre mediante la palabra reservada base que hace referencia a la clase padre. Despu•s de ejecutar dicho m•todo s€lo tendr…amos que ejecutar la funcionalidad extra que necesitemos.

37

Programaci€n orientada a objetos en Vala

Informaci€n de tipos en tiempo de ejecuci€n Puesto las clases en Vala se registran en el sistema en tiempo de ejecuci€n, cada instancia contiene informaci€n de su tipo que se puede consultar de forma din‚mica mediante el operador is: is: bool b bool  b = object is AlgunTipo;

Se puede obtener el informaci€n acerca del tipo de una instancia usando el m•todo definido get_type(). get_type(). Este m•todo est‚ definido en GLib.Object por lo que la clase del objeto desde la cual lo llamamos debe heredar de esta clase base. Type type = object object.get_type(); .get_type(); // Se obtiene el tipo y se almacena en una instancia del tipo "Type" stdout.printf( "%s\n" "%s\n", , type.name()); // Se muestra el nombre del tipo

Con el operador typeof() se puede acceder a la informaci€n del tipo de forma directa. A partir de la informaci€n del tipo obtenida se puede crear nuevas instancias con Object.new(). Object.new(). Ejemplo: Type type = typeof (Foo); // Se obtiene la informaci‚n del tipo de la instancia "Foo" Foo foo = (Foo) Object. new(type); // Se crea un nuevo objeto del tipo "type" y "type"  y se asigna a la referencia foo

En este caso el constructor que se utiliza para inicializar los objetos de esta forma ser‚ el descrito en la secci€n de los constructores estilo GObject.

Conversi€n de tipos din„mica Para la conversi€n din‚mica entre tipos una variable se convierte mediante una expresi€n posfija as y el tipo al que queremos convertir la referencia. Vala dispone de comprobaci€n de tipos din‚mica para asegurarse de que la conversi€n es factible. En caso de que la conversi€n sea imposible de realizar se devuelve null. null. Sin embargo, esto requiere que se especifique tanto el tipo de la clase origen como el destino. Ejemplo: Button b = widget as Button;

Si por alguna raz€n la clase de la instancia widget no es de tipo Button o una de las clase hijas de •sta o no implementa la interfaz Button, Button, b ser‚ null. null. Esta conversi€n es equivalente a la siguiente expresi€n: Button b = (widget is Button) ? (Button) widget : null;

Tipos genƒricos Vala incluye un sistema de tipos gen•rico, mediante el cual una instancia particular de una clase se puede restringir con un tipo particular o un conjunto de tipos elegidos en la construcci€n de la clase. Esta restricci€n se usa normalmente para asegurarse que los datos almacenados en un objeto deben ser de un tipo particular, por ejemplo para implementar una lista de objetos de un determinado tipo. En este ejemplo, Vala se asegura que s€lo los objetos del tipo indicado puedan ser a„adidos a la lista, y todos los objetos que sean devueltos ser‚n tambi•n de ese tipo (o convertidos a ese tipo). En Vala, los tipos gen•ricos (generics ( generics)) se gestionan cuando el programa se s e encuentra en ejecuci€n. Cuando se define una clase que puede ser restringida a un tipo de dato, existir‚ s€lo una clase, cuyas instancias ser‚n personalizadas individualmente. Esto es diferente a C++, d€nde se crea una nueva clase para cada tipo requerido. Vala es similar al sistema usado por Java en este sentido. Esto tiene varias consecuencias, la m‚s importante de ellas es que los miembros est‚ticos (static (static)) de un tipo se comparten como un todo, sin importar las restricciones que se encuentren

38

Programaci€n orientada a objetos en Vala en cada instancia; y eso dado una clase o una subclase, un tipo gen•rico refinado por una subclase puede ser usado como un tipo gen•rico refinado por la clase. Ejemplo:  public class  Wrapper : GLib.Object {  private G data;  public void  set_data set_data(G (G data) { this.data = data; }

 public G get_data get_data() () { return this.data; } }

La clase Wrapper debe ser restringida con un tipo para inicializarla, en este caso el tipo se identifica como G, y de esta manera las instancias de esta clase almacenar‚n un objeto del tipo G, y tendr‚n m•todos para obtener o modificar ese objeto. La raz€n de este ejemplo espec…fico es explicar que actualmente una clase de tipo gen•rico no puede usar propiedades es su restricci€n del tipo, por lo que debe usar m•todos para obtener y modificar este dato. Para inicializar esta clase, se debe elegir un tipo de dato, por ejemplo el tipo cadena (en Vala no existe restricci€n en el tipo de dtos que puede usarse en una clase gen•rica). Para crear una instancia de la clase: var wrapper = new Wrapper(); >(); wrapper.set_data("test" wrapper.set_data( "test"); ); var data = wrapper.get_data();

Como puede verse, cuando se obtiene los datos de la clase Wrapper, Wrapper, se asignan a un identificador con un tipo no expl…cito (que se define mediante la palabra reservada var). var). Esto es posible por que Vala sabe que tipo de objetos se encuentran en cada instancia de Wrapper, Wrapper, y por lo tanto puede realizar este trabajo por usted. El hecho de que Vala no cree varias clases para una definici€n gen•rica significa que se puede realizar un c€digo como el que sigue: class TestClass : GLib.Object { }

void  accept_object_wrapper (Wrapper w) { } ... var test_wrapper = new  Wrapper(); accept_object_wrapper(test_wrapper); ...

Puesto que todas las instancias de TestClass son tambi•n objetos GLib.Object, GLib.Object, el m•todo accept_object_wrapper aceptar‚ el objeto que le sea pasado, y lo tratar‚ como si fuera una instancia de un objeto GLib.Object. GLib.Object.

39

Programaci€n orientada a objetos en Vala

40

Esquema de construcci€n tipo GObject Como se coment€ anteriormente en este mismo cap…tulo, Vala ofrece un estilo de construcci€n alternativo que es diferente al anteriormente descrito, pero muy cercano a como se realiza la construcci€n de objetos con la biblioteca GObject. El m•todo que el programador prefiere depende de si se procede del estilo de programaci€n de GObject o de Java/C#. El estilo de construcci€n de objetos GObject introduce un nuevo elemento de sintaxis: las propiedades del constructor, una llamada especial a Object(...) y un bloque de constructor. Vamos a ver como funciona este tipo de constructor:  public class Person : Object { /* Propiedades del constructor */ 

 public string string name  name { get; construct; }  public int int age  age { get; construct set; }  public Person Person( (string string name)  name) { Object(name: name); }

 public Person.with_age( string string name,  name, int int years)  years) { Object(name: name, age: years); } construct { // Todo lo que tenga que hacer adicionalmente el constructor  stdout.printf( "Welcome %s\n", stdout.printf("Welcome %s\n" , this .name);

  } }

Con este esquema de construcci€n cada m•todo constructor contiene una llamada a GObject(...) para establecer las propiedades del constructor. La llamada a GObject(...) toma un n†mero variable de par‚metros con nombre en la forma propiedad : valor. valor. Estas propiedades deben ser declaradas como una propiedad del constructor. Se establecer‚n dichas propiedades a los valores dados despu•s de que todos los bloques de constructores desde el original GLib.Object hacia abajo hasta el de la clase actual se hayan ejecutado. Se garantiza la ejecuci€n del bloque del constructor cada vez que una clase es creada, incluso si es creada como un subtipo de la misma. No tiene ni un par‚metro ni un valor de retorno. Dentro de este bloque se puede realizar llamadas a otros m•todos y establecer el valor de miembros dato si es necesario. Las propiedades de construcci€n se definen como propiedades con bloques get y set para obtener establecer sus valores, y por lo tanto con c€digo arbitrario en la asignaci€n. Si se necesita realizar la inicializaci€n en una propiedad de un constructor, es posible escribir es cribir un bloque para esa propiedad, la cual se s e ejecutar‚ inmediatamente despu•s de la asignaci€n, y antes de cualquier c€digo de construcci€n. Si una propiedad de constructor se declara sin bloque set se denomina como una propiedad de construcci€n exclusiva, lo cual significa que s€lo puede ser asignada en la fase de construcci€n, pero no despu•s de esa fase. En el ejemplo de arriba la propiedad name es una propiedad de este tipo. A continuaci€n un resumen de los distintos tipos de propiedades junto con la nomenclatura que se encuentra en la librer…as de tipo GObject: GObject:  public int int a  a { get;  private set; }

// Lectura

 public int int b  b {  private get; set; }

// Escritura

 public int int c  c { get; set; }

// Lectura / Escritura

Programaci€n orientada a objetos en Vala

41

 public int int d  d { get; set construct; }

// Lectura / Escritura /

Construcciƒn

 public int int e  e { get; construct; }

// Lectura / Escritura / S‚lo

 Construcciƒn

Referencias [1] [1] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Lenguaje_de_programaci€n_multiparadigma Lenguaje_de_programaci€n_multiparadigma [2] [2] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Conteo_de_referencias Conteo_de_referencias [3] [3] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Recolector_de_basura Recolector_de_basura [4] [4] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Algoritmo_determinista Algoritmo_determinista [5] [5] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Patr%C3%B3n_de_dise%C3%B1o Patr%C3%B3n_de_dise%C3%B1o [6] [6] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ RAII RAII [7] [7] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Encapsulamiento_%28inform%C3%A1tica%29 Encapsulamiento_%28inform%C3%A1tica%29 [8] [8] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Glade Glade [9] [9] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Widget#Los_widget_en_el_.C3. Widget#Los_widget_en_el_.C3.A1mbito_de_la_programaci. A1mbito_de_la_programaci.C3. C3.B3n_gr. B3n_gr.C3. C3.A1fica A1fica [10] [10] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ GTK%2B GTK%2B [11] [11] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Polimorfismo_%28inform%C3%A1tica%29 Polimorfismo_%28inform%C3%A1tica%29

Funcionalidades avanzadas del lenguaje Aserciones y Dise…o por contrato Con las aserciones un programador puede comprobar que un predicado se cumple en tiempo de ejecuci€n. La sintaxis es assert( condici€n ). ). Si la aserci€n falla el programa terminar‚ su ejecuci€n con un mensaje de error que mostrar‚ tal circunstancia. Hay varios m•todos de aserciones definidos en la GLib y que el programador podr‚ usar, entre los que se encuentran:

Aserciones definidas en GLib Aserci€n

Descripci€n

assert_not_reached()

Esta aserci€n se ejecuta en el caso en el que se llegue a ejecutar la l…nea en la que se ha definido.

return_if_fail(expresi€n_booleana) Si la expresi€n booleana es falsa, un mensaje de error cr…tico se muestra y se finaliza la ejecuci€n de la funci€n. Esto s€lo se puede usar en m•todos que no devuelven ning†n valor. return_if_reached(val)

Si se ejecuta devuelve el valor val y cancela la ejecuci€n del m•todo.

warn_if_fail(expresi€n_booleana)

Muestra un mensaje de aviso si la expresi€n booleana resulta ser falsa.

warn_if_reached()

Si se ejecuta la l…nea d€nde se encuentra definido entonces se muestra un mensaje de error.

Puede que el lector quiera usar las aserciones para comprobar si los argumentos de un m•todo tienen valor o son null, null, sin embargo, esto no es necesario, ya que, Vala realiza esto de forma impl…cita sobre todos los par‚metros que no est‚n marcados con ? (el indicador de que pueden ser de valor null). null). void  method_name (Foo foo, Bar bar) { /* No es necesario por que Vala lo hace por t€!: return_if_fail(foo return_if_f ail(foo != null); return_if_fail(bar return_if_f ail(bar != null); */  }

Funcionalidades avanzadas del lenguaje Vala soporta las funcionalidades b‚sicas de el dise„o por contrato [1]. Un m•todo puede tener precondiciones (requires) (ensures)) que deben ser satisfechos al principio o al final de un m•todo requires) y postcondiciones (ensures respectivamente: double method_name (int int x,  x, double double d)  d) requires (x > 0 && x < 10 10) ) requires (d >= 0.0 0.0 &&  && d = 0.0 0.0 &&  && result : ->: o->method_1(); o->data_1;

Para liberar la memoria en la que se almacena el objeto (cuando •ste ya no sea †til): delete o;

Vala tiene soporte para los operadores de punteros que se usan en C, es decir, el operador direcci€n de (&) y el operador indirecci€n [14] (*). (*). El primer operador obtiene la direcci€n de memoria de un objeto y el segundo obtiene el propio objeto a partir de un puntero (se usa para acceder al contenido del objeto): int i int  i = 42 42; ;

// Un entero con valor 42

int* int * i_ptr = &i;

// Obtenemos un puntero que apunta al entero i

mediante el operador direcciƒn de int j int  j = *i_ptr;

// Mediante el operador indirecci‚n se obtiene el

contenido del entero 'i' 'i'. . *i_ptr = 7;

// Se modifica el valor del entero tambi„n mediante

 el operador indirecciƒn.

Cuando en lugar de valores primitivos (como en el caso anterior en el que se ha usado un entero) se usan referencia a objetos se pueden omitir los operadores, ya que, en este caso se est‚n usando sobre referencias que apuntan a los objetos. Foo f = new Foo(); Foo* f_ptr = f;

// Se obtiene la direcci‚n del objeto que apunta la

referencia 'f' Foo g = f_ptr;

// Se obtiene el contenido del objeto y se apunta

mediante una nueva referencia llamada 'g' unowned Foo f_weak = f;

// Esto es equivalente a la segunda l€nea de

cƒdigo

El uso de punteros es equivalente al uso de referencias sin propietario como se puede ver en el ejemplo de arriba en la †ltima l…nea de c€digo.

Clases que no heredan de GLib.Object Las clases que no hereden en ning†n nivel de GLib.Object son tratadas como un caso especial. Estas clases derivan directamente desde el sistema de tipos de GLib y por lo tanto son m‚s ligeras (en uso de recursos). Un caso obvio de este tipo de clases son algunos de los Binding [15] a la biblioteca GLib. Puesto que la biblioteca GLib hace un trabajo a m‚s bajo nivel que GObject, la mayor…a de las clases que se definen en el binding son de este tipo. Como se ha comentado anteriormente, estas clases son m‚s ligeras, lo cual las haces †tiles en algunos casos (por ejemplo en el uso del propio compilador de Vala). Sin embargo, el uso de este tipo de clases no es muy habitual por lo que no se tratar‚ en este documento.

Funcionalidades avanzadas del lenguaje

Referencias [1] [1] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Dise%C3%B1o_por_Contrato Dise%C3%B1o_por_Contrato [2] [2] http http:/  :/   / live.gnome. live.gnome.org/  org/ Libgee Libgee [3] [3] http http:/  :/   / www.valadoc. www.valadoc.org/  org/ gee-1.0/  gee-1.0/ Gee.ArrayList. Gee.ArrayList.html html [4] [4] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Hash Hash [5] [5] http http:/  :/   / www.valadoc. www.valadoc.org/  org/ gee-1.0/  gee-1.0/ Gee.HashMap. Gee.HashMap.html html [6] [6] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Violaci€n_de_acceso Violaci€n_de_acceso [7] [7] http http:/  :/   / www.gtk. www.gtk.org/  org/  [8] [8] http http:/  :/   / library.gnome. library.gnome.org/  org/ devel/  devel/ gtk/  gtk/ stable/  stable/  [9] [9] http http:/  :/   / valadoc.org/  valadoc.org/ gtk+-2. gtk+-2.0/  0/ index.html index.html [10] [10] http http:/  :/   / en.wikipedia. en.wikipedia.org/  org/ wiki/  wiki/ Continuation Continuation [11] [11] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Scheme Scheme [12] [12] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ %C3%81rbol_%28inform%C3%A1tica%29 %C3%81rbol_%28inform%C3%A1tica%29 [13] [13] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Lista_%28inform%C3%A1tica%29# Lista_%28inform%C3%A1tica%29#Lista_Doblemente_En Lista_Doblemente_Enlazada lazada [14] [14] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Indirecci%C3%B3n Indirecci%C3%B3n [15] [15] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Binding Binding

Funcionalidades experimentales del lenguaje Las funcionalidades que se presentan en este cap…tulo han sido definidas como experimentales y por lo tanto no se recomienda su uso hasta que se defina completamente el est‚ndar del lenguaje, ya que podr…a cambiar su sintaxis e incluso dejar de existir en una versi€n definitiva del compilador.

Expresiones relacionales encadenadas Esta funcionalidad del lenguaje permite escribir expresiones relacionales complejas como la siguiente: if (1  (1 < a && a < 5) {} if (0  (0 < a && a < b && b < c && c < d && d < 255 255) ) { // Acciones }

De una forma m‚s simple como la siguiente: if (1  (1 < a < 5) {} if (0  (0 < a < b < c < d < 255 255) ) { // Acciones }

De esta forma se encadenan los valores y nos aseguramos que la condici€n sea cierta antes de que se ejecuten las acciones. Esta forma de escribir la expresi€n relacional es m‚s natural y semejante a como se define de forma matem‚tica la expresi€n.

63

Funcionalidades experimentales del lenguaje

64

Expresiones regulares en literales Las expresiones regulares [1] son una t•cnica muy potente para tratar cadenas de texto y realizar operaciones de b†squeda de patrones entre otros usos. Vala dispone de funcionalidad experimental con expresiones regulares en literales de una forma similar a como lo hace el lenguaje de programaci€n Perl [2]. Vala utiliza el operador  /expresion-regular/ para definir un objeto de tipo Regex. Regex. Por ejemplo: string email string  email = "[email protected]" ;

if (/^[A-Z0-9.  (/^[A-Z0- 9._%+-]+@[A-Z0_%+-]+@[A-Z0- 9. 9.-]+\.[A-Z]{ -]+\.[A-Z]{ 2,4}$/i.match(email)) {  

stdout.printf( "Direcciƒn de correo v€lida\n" ); stdout.printf("Direcciƒn

}

El modificador i que aparece despu•s de la definici€n de la expresi€n regular y antes de la llamada al m•todo match(email) hace que la expresi€n regular sea insensible a las may†sculas. Se puede almacenar una expresi€n regular en un objeto de tipo Regex: Regex: Regex regex = /foo/;

Las expresiones regulares son una t•cnica de una complejidad suficiente como para dedicarles un documento separado del actual por lo que si el lector desea conocer m‚s sobre el uso de expresiones regulares en Vala puede usar los siguientes enlaces para satisfaces su curiosidad: ‡ Expresi Expresione oness regul regulare aress con con GLib GLib [3]. (Esta es la sintaxis que se usa en Vala). ‡ Expresi Expresione oness regu regular lares es en Vala Vala [4]. (Documentaci€n oficial de Vala).

Modo no-nulo estricto Si se compilan programas con la opci€n --enable-experimental-non-null el compilador de Vala ejecutar‚ una serie de comprobaciones est‚ticas considerando todos los tipos como no nulos por defecto a menos que sean declarados como posibles nulos con el modificador ?. Object o1 = new Object();

// No puede ser nulo

Object? o2 = new Object();

// Puede ser nulo

El compilador realizar‚ un an‚lisis en tiempo de compilaci€n para asegurarse de que las referencias se asigna a referencias que no pueden se nulas. Por ejemplo, en este modo de compilaci€n, el siguiente c€digo no compilar…a y dar…a un error: Object o1 = new Object();

// No puede ser nulo

Object? o2 = new Object();

// Puede ser nulo

o1 = o2;

La referencia o2 ha sido marcada como una referencia que puede tener el valor nulo mientras que o1 no puede ser nulo. Sin embargo se puede evitar este comportamiento por defecto del compilador mediante el uso de la conversi€n a un tipo no nulo expl…cita, siempre que estemos seguros de que la referencia no sea nula: o1 = (!) o2;

El modo no nulo estricto ayuda a evitar errores con referencias que tienen valores nulos. Esta caracter…stica ser…a complete si la posibilidad de valor nulo de todos los valores de retorno en las librerias estuviera marcada de forma correcta, pero actualmente no siempre se hace.

Funcionalidades experimentales del lenguaje

Referencias [1] [1] [2] [2] [3] [3] [4] [4]

http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Expresi%C3%B3n_regular Expresi%C3%B3n_regular http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Perl#Expresiones_regulares Perl#Expresiones_regulares http http:/  :/   / library.gnome. library.gnome.org/  org/ devel/  devel/ glib/  glib/ stable/  stable/ glib-regex-syntax.html glib-regex-syntax.html http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Regex. GLib.Regex.html html

Bibliotecas del lenguaje Esta secci€n se encargar‚ de describir el uso de las principales bibliotecas que se necesitan en la mayor…a de los casos a la hora de desarrollar una aplicaci€n. Sin embargo no se tratar‚ la gran cantidad de bibliotecas que existen dentro del lenguaje de programaci€n Vala, ya que existen diversas documentaciones sobre cada biblioteca espec…fica. As…  para consultar todas las bibliotecas que son accesibles desde el lenguaje en la actualidad se puede consultar la p‚gina de documentaci€n de vala [1].

Acceso a ficheros en Vala (biblioteca GIO) La biblioteca de funciones GIO [2] es similar en funcionalidad al framework IO de Java. Esta biblioteca contiene objetos para el trabajo con ficheros, tanto para lectura como para escritura. Contiene dos clases base, una para lectura y otra para escritura: InputStream y OutputStream. OutputStream. Cuando se abre un fichero para su lectura se obtiene una referencia a un objeto de la clase InputStream. InputStream. Los flujos se pueden usar con el patr€n de dise„o decorador [3] para suministrar funcionalidad adicional. Por ejemplo es posible leer el contenido de un fichero l…nea a l…nea mediante un DataInputStream. DataInputStream. O se puede aplicar un FileInputStream para realizar alg†n filtrado de datos.

Leer un fichero l‡nea a l‡nea El siguiente ejemplo lee el contenido de un fichero de texto l…nea a l…nea y escribe el texto por pantalla. static int main main (  (string string[] [] args) { // Referencia a un fichero llamado 'data.txt' var file = File.new_for_path File.new_for_path ( "data.txt" );

if (!file.query_exists ( null)) { // Se comprueba si el fichero existe o no stderr.printf stderr.print f ( "File '%s' doesn't exist.\n" , file.get_path ()); // No existe y se muestra un mensaje de error 

return 1; }

try { // Se abre un fichero para lectura y se convierte el FileInputStream FileInputStream en un // DataInputStream, para que se pueda leer l€nea a l€nea var in_stream = new DataInputStream (file.read ( null )); string line; string  line; // Se lee la l€nea hasta que se devuelva un null que indica que  se ha llegado al final del fichero while ((line while  ((line = in_stream.read_line in_stream.read_line ( null, null)) != null ) {

65

Bibliotecas del lenguaje stdout.printf ( "%s\n" "%s\n", , line); } } catch (Error e) { // Si se produce un error se muestra error ("%s" "%s", , e.message); }

return 0; }

Referencias [1] [1] http http:/  :/   / valadoc.org/  valadoc.org/  [2] [2] http http:/  :/   / library.gnome. library.gnome.org/  org/ devel/  devel/ gio/  gio/ stable/  stable/  [3] [3] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Decorator_(patr€n_de_dise„o) Decorator_(patr€n_de_dise„o)

Herramientas Las herramientas para compilar un programa escrito en Vala son muy sencillas: En primer lugar, y ante todo, el compilador Valac, y en segundo lugar un editor de texto plano, no un procesador de palabras (como GEdit, no uses programas parecidos a LibreOffice Writer). Podemos usar un IDE como Geany para mayor comodidad. Esta es decisi€n del programador. Te mostraremos las opciones a configurar y ser‚ tu decisi€n la v…a que usar‚s para desarrollar tus aplicaciones.

Instalando el compilador Valac El compilador Valac se puede instalar de dos formas: Desde los repositorios de software de tu distribuci€n GNU/Linux o bien desde el c€digo fuente descargado de la p‚gina oficial del proyecto Vala.

Desde los repositorios de software El compilador se encuentra (a veces en versiones desactualizadas) en los repositorios de software de la mayor…a de las distribuciones GNU/Linux. Lo puedes instalar si tienes Debian/Ubuntu o derivados con apt-get install valac

O bien si tu distribuci€n es basada en RPM (Fedora) con el comando yum install vala

Los usuarios de Arch Linux no tendr‚n problemas en tener el paquete actualizado, pues esta distribuci€n se caracteriza por siempre ir al corriente en cuanto a las †ltimas versiones de todos los paquetes de Software, basta instalarlo con el comando pacman -S vala

66

Herramientas

Desde el c€digo fuente Si no deseas obtener el compilador como paquete de tu distribuci€n por alguna raz€n (como lo es que el paquete est• desactualizado) siempre lo puedes descargar y compilar por ti mismo. El compilador Valac puede ser descargado del sitio web oficial de Vala [1]. Obtendr‚s un archivo nombrado como vala-x.x.x.tar.xz, vala-x.x.x.tar.xz, donde las  x representan el n†mero de la versi€n descargada, como puede ser vala-0.15.0.tar.xz. vala-0.15.0.tar.xz. Descomprime el archivo desde tu terminal: tar -Jxf vala-0.15.0.tar.xz

Sustituye los n†meros de la versi€n por la versi€n del lanzamiento que hayas descargado. Luego, una vez descomprimido el archivo, mu•vete a la ruta del directorio del compilador, en este caso a la carpeta vala-0.15.0 cd vala-0.15.0

y ejecuta los comandos de construcci€n como los siguientes: ./configure --prefix=/usr

Si todo sale bien, se crear‚n los Makefiles para que puedas comenzar la compilaci€n (proceso que tarda de acuerdo a la capacidad de tu computadora, variando al rededor de 3 minutos). Pero si no tuviste •xito, revisa que tengas los archivos de desarrollo de GLib, de tener Ubuntu/Debian o alg†n derivado, instala el paquete libglib2.0-dev, libglib2.0-dev, si usas una distribuci€n basada en RPM, busca el paquete glib2-devel. glib2-devel. Cuando hayas completado lo anterior, contin†a el proceso simplemente ejecutando: make

Y si la compilaci€n tuvo •xito, puedes terminar el proceso de instalaci€n ejecutando -con privilegios administrativos- el comando make install

Y al finalizar, para asegurarte de que todo haya tenido •xito, puedes revisar la versi€n del compilador que tienes instalada en tu sistema, con el comando valac --version

Y dicho comando deber‚ devolver una salida con la versi€n que hemos instalado del compilador, en nuestro caso de ejemplo, la salida ser‚ [root@machine vala-0.15.0]# valac --version Vala 0.15.0

Y con esto nos hemos asegurado de instalar exitosamente el compilador Valac en nuestra computadora.

67

Herramientas

El editor de textos El editor de textos que usaremos para crear nuestros programas ser‚ un editor de texto plano, en el caso de la plataforma GNOME y en casi todas las distribuciones GNU/Linux tenemos por defecto el editor de texto Gedit.

Gedit Este editor nos da la caracter…stica de resaltado de palabras clave del lenguaje, puede ser configurado para resaltar parejas de corchetes (algo que es †til cuando tenemos un programa muy jerarquizado) y nos puede mostrar los n†meros de l…nea en que nos encontramos. Para usarlo, simplemente tenemos que abrirlo, crear un archivo de c€digo fuente y colocarle la extensi€n del archivo .vala para que el editor autom‚ticamente detecte el tipo de lenguaje que manejamos y nos resalte las palabras clave. La desventaja de usarlo es que tendremos que guardar los archivos de c€digo fuente cada vez que deseemos realizar una compilaci€n y abrir una terminal para hacerla. Luego en la terminal teclear el comando para la construcci€n y, si existieran errores, estos ser…an mostrados en pantalla, pero tendr…amos que buscar la l…nea de c€digo err€nea en el archivo de c€digo fuente en Gedit, no en la terminal.

GNU Nano No se recomienda el uso de este programa para usuarios novatos o sin experiencia en el uso extenso de la terminal, pero es una opci€n en caso de no disponer de alguna otra alternativa para editar textos, casi todas las distribuciones GNU/Linux, independientemente del entorno del escritorio que tengamos (GNOME, KDE, XFCE, LXDE, etc) lo traen incluido. Este es un editor de texto en modo consola, es decir que para poder usarlo tendremos que abrir una terminal y teclear el comando invocando al programa, de la forma nano archivo.vala

donde archivo.vala es el nombre del archivo de c€digo fuente que deseamos editar, ya sea que exista o que deseemos crearlo. La lista de opciones que usaremos ser‚ limitada, no existe un resaltado de sintaxis ni un conteo de n†meros de l…nea tal como lo tenemos en Gedit o en otros editores especializados. Las opciones b‚sicas que usaremos ser‚n ‡ ‡ ‡ ‡

Ctrl + o para guardar el archivo actual. Ctrl + x para salir del editor. Ctrl + w para buscar una cadena de texto en el documento.

y Ctrl + g para ver la ayuda.

Y de la misma forma en que usamos Gedit para compilar un archivo de c€digo fuente, tendremos que guardar los cambios antes de compilar, y debemos buscar manualmente las l…neas que contengan errores y corregirlas, para repetir el proceso hasta la finalizaci€n del desarrollo de nuestros programas.

68

Herramientas

Usar un IDE IDE son siglas inglesas para un entorno integrado de desarollo, y es que precisamente en un programa como Geany tenemos todas las opciones de configuraci€n que necesitamos para desarrollar (sin salir de ah…) nuestros programas escritos en varios lenguajes de programaci€n. En primer lugar, debemos instalar Geany desde nuestros repositorios de Softwawe, y cuando est• instalado simplemente tenemos que abrir nuestros archivos de c€digo fuente en Vala y el editor integrado nos dar‚ el resaltado de sintaxis y la terminal incluida debajo o bien las opciones de compilaci€n r‚pida nos dar‚n la ayuda que necesitamos para desarrollar nuestros programas de forma eficiente.

Otras tƒcnicas El compilador Valac est‚ basado en el modelo de objetos de GLib y GObject. Todos los programas que escribimos en lenguaje Vala son traducidos a lenguaje C y luego con el compilador GCC son compilados a c€digo de m‚quina. Por esto mismo, los programas en Vala escritos de esta forma void main void  main () {  

stdout.printf( "Programa de prueba" ); stdout.printf("Programa

}

Tienen de forma oculta un namespace sin mostrarlo, ya que es agregado autom‚ticamente al compilador, de forma que el programa anterior es equivalente al siguiente using GLib; // Aunque esta l€nea no es necesaria. void main void  main () {  

stdout.printf( "Programa de prueba" ); stdout.printf("Programa

}

Y es que la clase stdout es miembro de GLib, por tanto suceder‚ que si escribimos o no el namespace este se usar‚.

Namespaces de GLib Una lista de los namespaces de GLib [1] es: ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡

Math [2] Definciones num•ricas, constantes matem‚ticas y descomposici€n de puntos flotantes [3]. AtomicInt [4] Operaciones at€micas - Operaciones b‚sicas para enteros at€micos [5]. Atom Atomic icPo Poin inte terr [6] Operaciones at€micas - Operaciones b‚sicas para punteros at€micos [7] Priority [8] Timeout [9] Idle [10] ChildWatch [11] Memory [12] Slice [13] Log [14] Filename [15] Base64 [16] Codifica y decodifica datos en Base 64 [17]. Random [18] Generador de n†meros pseudo-aleatorios [19]. Env Environ ironm ment ent [20] KeyF KeyFil ileD eDes eskt ktop op [21]

69

Otras t•cnicas ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡ ‡

Bit [22] Spac SpaceedPri dPrime mess [23] Cha Charact racter erSe Sett [24] Process [25] FileUtils [26] Algunas funciones para manejo de archivos [27]. DirUtils [28] Uri [29] Shell [30] Markup [31] KeyF KeyFil ileD eDes eskt ktop op [21] Test [32] Intl [33] Win32 [34]

Y cabe decir que todos estos namespaces, cada uno con todas sus clases y funciones est‚n disponibles para su uso con el compilador Valac sin agregar otra librer…a o namespace.

Ejemplo de uso de un Namespace de GLib Como ya lo dijimos, los Namespaces de GLib pueden ser usados en cualquier momento en los programas escritos en Vala que hagamos. Para ejemplificarlo veremos una ejemplo pr‚ctico y sencillo: Dado el valor de un ‚ngulo, deseamos conocer el valor del seno matem‚tico de •ste. Para eso, recurriremos al Namespace Math de GLib, usando la funci€n  Math.sin() para conocer el valor de dicha operaci€n (expresada en Radianes [35]). Dicho programa tendr…a la siguiente forma: void main void  main () {  

stdout.printf( "Dame el valor de un €ngulo: " ); stdout.printf("Dame string entrada string  entrada =  stdin.read_line(); double resultado double  resultado = Math.sin( double double.parse(angu .parse(angulo) lo) );

 

stdout.printf( "El seno de %s es %d radianes \n", entrada, resultado); stdout.printf("El

}

Explicando el programa, tenemos que en primer lugar, se imprime la l…nea indicando la entrada de un ‚ngulo. En la siguiente l…nea se crea una cadena de texto, llamada entrada, y el valor de esa cadena de texto se asigna mediante la funci€n stdin.read_line(). Luego, se crea un flotante de precisi€n doble, llamado resultado, y el valor de dicho resultado es la salida de la funci€n Math.sin(), y como par‚metro a dicha funci€n se asigna el valor de la cadena de texto entrada. Pero como se trata de una cadena de texto (string), hacemos una conversi€n hacia un flotante de precisi€n doble con la funci€n double.parse(). Luego, se imprimen los resultados en pantalla. El indicador %s indica que se pasa una cadena de texto (string), y el indicador %d indica que se pasa un flotante de precisi€n doble(double). Y a esos par‚metros se pasan los par‚metros entrada y resultado. resultado. Este ejemplo fue algo sencillo para explicar los Namespaces de GLib, y cada uno de ellos tiene su forma de uso, pero b‚sicamente se utilizan de esa forma.

70

Otras t•cnicas

Referencias [1] [1] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.html GLib.html [2] [2] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Math. GLib.Math.html html [3] [3] http http:/  :/   / developer.gnome. developer.gnome.org/  org/ glib/  glib/ 2.28/  2.28/ glib-Numerical-Definitions.html glib-Numerical-Definitions.html [4] [4] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.AtomicInt. GLib.AtomicInt.html html [5] [5] http http:/  :/   / developer.gnome. developer.gnome.org/  org/ glib/  glib/ 2.28/  2.28/ glib-Atomic-Operations.html glib-Atomic-Operations.html [6] [6] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.AtomicPointer. GLib.AtomicPointer.html html [7] [7] http http:/  :/   / developer.gnome. developer.gnome.org/  org/ glib/  glib/ 2.28/  2.28/ glib-Atomic-Operations.html glib-Atomic-Operations.html [8] [8] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Priority. GLib.Priority.html html [9] [9] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Timeout. GLib.Timeout.html html [10] [10] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Idle. GLib.Idle.html html [11] [11] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.ChildWatch. GLib.ChildWatch.html html [12] [12] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Memory. GLib.Memory.html html [13] [13] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Slice. GLib.Slice.html html [14] [14] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Log. GLib.Log.html html [15] [15] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Filename. GLib.Filename.html html [16] [16] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Base64. GLib.Base64.html html [17] [17] http http:/  :/   / developer.gnome. developer.gnome.org/  org/ glib/  glib/ 2.28/  2.28/  [18] [18] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Random. GLib.Random.html html [19] [19] http http:/  :/   / developer.gnome. developer.gnome.org/  org/ glib/  glib/ 2.28/  2.28/ glib-Random-Numbers.html glib-Random-Numbers.html [20] [20] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Environment. GLib.Environment.html html [21] [21] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.KeyFileDesktop. GLib.KeyFileDesktop.html html [22] [22] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Bit. GLib.Bit.html html [23] [23] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.SpacedPrimes. GLib.SpacedPrimes.html html [24] [24] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.CharacterSet. GLib.CharacterSet.html html [25] [25] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Process. GLib.Process.html html [26] [26] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.FileUtils. GLib.FileUtils.html html [27] [27] http http:/  :/   / developer.gnome. developer.gnome.org/  org/ glib/  glib/ 2.28/  2.28/  [28] [28] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.DirUtils. GLib.DirUtils.html html [29] [29] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Uri. GLib.Uri.html html [30] [30] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Shell. GLib.Shell.html html [31] [31] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Markup. GLib.Markup.html html [32] [32] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Test. GLib.Test.html html [33] [33] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Intl. GLib.Intl.html html [34] [34] http http:/  :/   / valadoc.org/  valadoc.org/ glib-2.0/  glib-2.0/ GLib.Win32. GLib.Win32.html html [35] [35] http http:/  :/   / es.wikipedia. es.wikipedia.org/  org/ wiki/  wiki/ Radian Radian

71

Fuentes y contribuyentes del art…culo

Fuentes y contribuyentes del art‡culo http://es.wikibooks.org/w/index.php?oldid=192013 192013 Contribuyentes: Sigmar, 9 ediciones an€nimas Programaci€n en Vala  Fuente: http://es.wikibooks.org/w/index.php?oldid= http://es.wikibooks.org/w/index.php?oldid=182078 =182078 Contribuyentes: Sigmar, 11 ediciones an€nimas Introducci€n  Fuente: http://es.wikibooks.org/w/index.php?oldid http://es.wikibooks.org/w/index.php?oldid=154216 d=154216 Contribuyentes: Sigmar, 2 ediciones an€nimas Su primer programa en Vala  Fuente: http://es.wikibooks.org/w/index.php?oldi http://es.wikibooks.org/w/index.php?oldid=190592 =190592 Contribuyentes: Sigmar, 10 ediciones an€nimas Conceptos b„sicos del lenguaje  Fuente: http://es.wikibooks.org/w/index.php?oldid http://es.wikibooks.org/w/index.php?oldid=155147 =155147 Contribuyentes: Sigmar Programaci€n orientada a objetos en Vala  Fuente: http://es.wikibooks.org/w/index.php?oldid http://es.wikibooks.org/w/index.php?oldid=157213 157213 Contribuyentes: Sigmar, 1 ediciones an€nimas Funcionalidades avanzadas del lenguaje  Fuente: http://es.wikibooks.org/w/index.php?oldid= http://es.wikibooks.org/w/index.php?oldid=157203 157203 Contribuyentes: Sigmar Funcionalidades experimentales del lenguaje  Fuente: http://es.wikibooks.org/w/index.php?oldid= http://es.wikibooks.org/w/index.php?oldid=157350 d=157350 Contribuyentes: Sigmar Bibliotecas del lenguaje  Fuente: http://es.wikibooks.org/w/index.php?oldi Herramientas  Fuente: http://es.wikibooks.org/w/index.php?oldid=1 http://es.wikibooks.org/w/index.php?oldid=177967 77967 Contribuyentes: TheOrlSan Otras tƒcnicas  Fuente: http://es.wikibooks.org/w/index.php?oldid http://es.wikibooks.org/w/index.php?oldid=178070 =178070 Contribuyentes: TheOrlSan

72

Fuentes de imagen, Licencias y contribuyentes

Fuentes de imagen, Licencias y contribuyentes Archivo:Doubly linked list insert after.png  Fuente: http://es.wikibooks.org/w/index.php?titl http://es.wikibooks.org/w/index.php?title=Archivo:Doubly_linked_li e=Archivo:Doubly_linked_list_insert_after.png st_insert_after.png  Licencia: Public Domain Contribuyentes: Original uploader was Fripp at it.wikipedia

73

Licencia

Licencia Creative Commons Attribution-Share Alike 3.0 Unported  //creativecommons.org/licenses/by-sa/3.0/   //creativecommons.org/licenses/by-sa/3.0/ 

74

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF