Diferencias entre las revisiones 2 y 3
Versión 2 con fecha 2010-05-26 20:57:59
Tamaño: 6284
Editor: DavidHoces
Comentario:
Versión 3 con fecha 2010-05-28 21:34:47
Tamaño: 12028
Editor: DavidHoces
Comentario: Ampliación hasta los delegados en Vala
Los textos eliminados se marcan así. Los textos añadidos se marcan así.
Línea 14: Línea 14:
Este documento es un resumen de las características del lenguaje de programación [[http://es.wikipedia.org/wiki/Vala_%28lenguaje_de_programaci%C3%B3n%29 | Vala]]. Diseñado para el sistema GObject de GNOME. Este documento es un resumen de las características del lenguaje de programación [[http://es.wikipedia.org/wiki/Vala_%28lenguaje_de_programaci%C3%B3n%29 | Vala]]. Diseñado para el sistema [[http://es.wikipedia.org/wiki/GObject | GObject]] de GNOME.
Línea 38: Línea 38:
  * '''long, ulong''' (unsigned long). Es un "long int" de C. El estándar no especifica cuánto más grande que integer debe ser una variable long integer. Sólo dice que no puede ser menor. Por lo tanto puede que incluso tengan el mismo tamaño.
  * '''short, ushort''' (unsigned short). Es un "short int" de C. Como en el caso anterior no está determinado un tamaño concreto. Sirve para indicarle al compilador que no vamos a usar todo el tamaño definido para int y así, posiblemente, ahorrar memoria.
  * '''long, ulong''' (unsigned long). Es un ''long int'' de C. El estándar no especifica cuánto más grande que integer debe ser una variable long integer. Sólo dice que no puede ser menor. Por lo tanto puede que incluso tengan el mismo tamaño.
  * '''short, ushort''' (unsigned short). Es un ''short int'' de C. Como en el caso anterior no está determinado un tamaño concreto. Sirve para indicarle al compilador que no vamos a usar todo el tamaño definido para int y así, posiblemente, ahorrar memoria.
Línea 63: Línea 63:
Además, es posible partir una cadena de caracteres utilizando la expresión [inicio:fin]. Donde ''inicio'' es la posición (incluyente) del primer caracter (empezando en 0) y ''fin'' es la posición (excluyente) del último carácter: Además, es posible partir una cadena de caracteres utilizando la expresión [inicio:fin]. Donde ''inicio'' es la posición (incluyente) del primer carácter (empezando en 0) y ''fin'' es la posición (excluyente) del último carácter:
Línea 84: Línea 84:

=== Arrays ===

Se pueden definir Arrays de cualquier tipo.
Ejemplo de Array unidimensional: {{{
in[] a = new int[10];
int[] b = {2,5,6,1};
}}}

Ejemplo de Array multidimensional:{{{
int[,] c = new int[3,4];
int[,] d = {{1,1},{2,2}};
}}}

Sólo si el array es local o privado, es posible añadir elementos dinámicamente. Y su tamaño se va incrementando en potencias de 2. Esto se hace con el operador '+=': {{{
int[] e;
e += 12;
e += 5;
}}}

El atributo '''length''' muestra el número de elementos del ''array''. Que no tiene porque corresponderse con su tamaño interno.

Es posible establecer el tamaño fijo del ''array'' en su declaración. Y en este caso no hace falta instanciar el tipo con el operador '''new()''':{{{
int f[10];
}}}

Por lo visto, todavía no están soportados los ''arrays'' multidimensionales irregulares. Donde cada dimensión es de un tamaño diferente:{{{
int[5][3];
}}}


=== Tipos dinámicos ===

También se pueden utilizar tipos dinámicos declarando las variables con '''var''':{{{
var a = 32;
var b = "hola";
}}}

Esto es muy útil para reducir la redundancia en el código. En java, por ejemplo, con la introducción de los [[http://en.wikipedia.org/wiki/Java_%28programming_language%29#Generics | tipos genéricos]], tendríamos el siguiente código para la instanciación de una clase:{{{
#!java numbers=off
MiAlgo<string, MiOtro<string, int>> algo = new MiAlgo<string, MiOtro<string, int>>();
}}}
La misma instanciación podría haber quedado resuelta, utilizando tipos dinámicos, de la siguiente manera (tal como se hace en [[http://es.wikipedia.org/wiki/Groovy_%28Lenguaje_de_Programaci%C3%B3n%29 | Groovy]]): {{{
var algo = new MiAlgo<string, MiOtro<string, int>>();
}}}

== Operadores ==

||<:>'''Operadores (separados por comas)'''||<:>'''Descripción'''||
||=||'''Operador de asignación''': asigna un valor a una variable.||
||+, -, /, *, %||'''Operadores aritméticos''': suma, resta, división, multiplicación y módulo.||
||+=, -=, /=, *=, %=||'''Operadores aritméticos''' en los que a la izquierda debe haber un operando al que asignar el resultado.||
||++, --||'''Incremento y decremento''' del valor de una variable respectivamente.||
|||, ^, &, ~ ||'''Operadores de comparación a nivel de bit''': ''or'', ''or'' exclusivo, ''and'' y ''not''.||
|||=, &=, ^= ||'''Modificadores de bits''' en los que a la izquierda debe haber un operando al que asignar el resultado: ''or'', ''or'' exclusivo, ''and'' y ''not''. ||
||<<, >>||'''Modificadores de bits''': el resultado de mover hacia la izquierda y hacia la derecha, respectivamente, los bits de una variable. Tantas posiciones como indique el operando de la derecha.||
|| <, >, ==||'''Operadores lógicos de comparación''': menor, mayor e igualdad, respectivamente.||
||!, &&, ||'''Operadores lógicos''': ''not'', ''and'' y ''or'', respectivamente.||
||(expresión)?(valor en verdadero):(valor en falso)||'''Operador condicional ternario'''. Evalúa una condición y devuelve el resultado según si la expresión es verdadera o falsa.||
||??||'''Operador de prevención de nulo'''. Establece un valor predeterminado en caso de que una referencia sea nula. Por ejemplo: {{{x = a??b}}} Es equivalente a {{{x = (a != null) ? a : b}}}.||
||as||'''Operador de casting de tipo dinámico'''. Comprueba, en tiempo de ejecución, que el tipo sea correcto. En caso contrario se asigna un valor nulo. Por ejemplo:{{{Button b = widget as Button}}} es equivalente a {{{Button b = (widget is Button) ? (Button) widget : null;}}}.||
||=>|| Expresión [[http://msdn.microsoft.com/es-es/library/bb397687%28v=VS.90%29.aspx | lambda]] para funciones anónimas.||
||while, do while, for, foreach, switch||'''Operadores de control'''.||

== Funciones ==

Los nombres de las funciones en Vala (también llamados métodos) siguen la convención de utilizar letras minúsculas y un guión bajo para separar palabras. Se utiliza el guión bajo en vez de la [[http://es.wikipedia.org/wiki/CamelCase | notación en camello]] porque es más coherente con los nombres de las funciones de las librerías de Vala y ''GObject''.

No existe la sobreescritura de métodos. Esto significa que no pueden existir dos métodos con el mismo nombre aunque éstos tengan distintos parámetros. El motivo es que las funciones escritas en Vala tambén deberían ser usables por programadores de C.

Es posible establecer un valor predeterminado para el argumento de un método. Así se puede simular el uso, común en otros lenguajes como Java, de métodos con el mismo nombre y número creciente de argumentos.

Por ejemplo, en Vala:
{{{
void f(in x, string s="hola", double z = 0.5){...};
}}}

Serviría para hacer lo que en Java sería:
{{{
void f(int x, string s, double z){...};
void f(int x, string s) { f(x, s, 0.5}; }
void f(int x) { f(x, "hola"); }
}}}

Vala hace una comprobación básica de valores nulos en los argumentos y devoluciones de los métodos. Por este motivo hay que indicar qué argumentos pueden tener valor nulo. En el siguiente ejemplo, tanto el valor de retorno como los argumentos ''texto'' y ''objeto'' pueden tener un valor nulo:

{{{
string? nombre_funcion (string? texto, Clase? objeto, int entero)
}}}

== Delegados ==

Existen tipos [[http://es.wikipedia.org/wiki/Delegaci%C3%B3n_%28inform%C3%A1tica%29|delegados]] (punteros a funciones). Así se pude pasar una función como parámetro a otra función. Por ejemplo:
{{{
//definir un tipo delegado
delegate void tipo_delegado(int a);
void funcion1 (int a){...}
void funcion2 (tipo_delegado d, int a){ d(a); }
...
 funcion2(funcion1, 5);
}}}

El lenguaje de programación Gnome Vala

ARTÍCULO EN DESARROLLO

Si quieres colaborar con nosotros completando este apartado o cualquier otra parte del Curso, puedes informarte en el enlace siguiente.

>[Documentación para desarrolladores]

Introducción

Este documento es un resumen de las características del lenguaje de programación Vala. Diseñado para el sistema GObject de GNOME.

Ficheros fuente

No hay restricciones en la escritura del código fuente. Esto significa que se pueden crear tantas clases como se quieran dentro del mismo fichero. En algunos lenguajes de programación hay que cumplir unas reglas. Por ejemplo: en java, el nombre del fichero con el código fuente se tiene que corresponder con el nombre de la clase que se está definiendo; y los nombres de los directorios se tienen que corresponder con los nombres de los paquetes que se están implementando.

El enfoque quizás sea parecido al que se sigue en el lenguaje de programación C. Donde todas las funciones de una misma librería se agrupan en un fichero objeto. Por este motivo, para crear un paquete, es necesario compilar a un fichero binario pasando al compilador todos los ficheros fuente necesarios. Y posteriormente es posible incluir ese paquete, al compilar otro fichero, indicándoselo al compilador mediante el parámetro "--pkg".

Tipos de datos

Se diferencian tres tipos de datos:

  • Tipos por referencia: los valores no son copiados cuando se asigna a un nuevo identificador. Lo que se copia es su referencia. Son tipos por referencia cualquier tipo definido con el modificador class. Independientemente de que descienda, o no, de Glib.Object.

  • Tipos por valor: los valores son copiados cuando se asigna a un nuevo identificador. Esto permite operar con cada identificador de forma independiente ya que las modificaciones que se hagan en uno no afectan al otro.

  • Constantes. Las constantes se definen utilizando el modificador const delante del tipo. Por convención, los nombres de las constantes deben ser en LETRAS_MAYÚSCULAS separadas por guiones bajos.

A continuación los tipos de datos soportados en el lenguaje.

Tipos por valor

Los siguientes tipos son equivalentes a los soportados por compiladores de lenguaje C. Estos tipos pueden tener tamaños diferentes según la arquitectura del computador en el que se vaya a compilar:

  • unichar. Es un character unicode UTF-8. Por ejemplo 'u'.

  • char, uchar (unsigned char). Es un byte de C.

  • int, uint (unsigned int). Es un int de C. En una arquitectura x86 tiene un tamaño de 4 bytes.

  • long, ulong (unsigned long). Es un long int de C. El estándar no especifica cuánto más grande que integer debe ser una variable long integer. Sólo dice que no puede ser menor. Por lo tanto puede que incluso tengan el mismo tamaño.

  • short, ushort (unsigned short). Es un short int de C. Como en el caso anterior no está determinado un tamaño concreto. Sirve para indicarle al compilador que no vamos a usar todo el tamaño definido para int y así, posiblemente, ahorrar memoria.

  • float. Es un float de C. Para números de coma flotante. En arquitecturas x86 tiene un tamaño de 4 bytes.

  • double. Es un double de C. Para números de coma flotante de precisión doble. En arquitecturas x86 tiene un tamaño de 8 bytes.

En cualquier caso, es posible determinar el tamaño mínimo y máximo de un tipo númerico utilizando los atributos .MIN y .MAX respectivamente: short.MIN.

A continuación los tipos específicos de Vala (y de cualquier lenguaje de alto nivel moderno como Java o C#):

  • bool. Tipo booleano cuyos valores pueden ser true o false.

  • struct. Para estructuras o también llamados tipos compuestos.

  • enum. Para enumeraciones. Representadas por valores enteros (no por clases como ocurre en las enumeraciones de Java).

  • string. Para cadenas de texto UTF-8. Al contrario de lo que ocurre en Java, se puede utilizar el operador == para comparar dos tipos string. Esto es debido a que se trata de un tipo por valor.

Cadenas de caracteres (Strings)

Señalar que, además del tipo de dato string mencionado anteriormente, también existen tipos de strings más complejos:

  • verbatim strings. Cadenas de texto sin interpretación de secuencias de escape (saltos de línea, tabulaciones, comillas, etc). Para definir un verbatim string hay que introducir la cadena de caracteres dentro de tripes comillas:

    """Hola.\n esto es un ejemplo de "texto bruto".
    Los saltos de línea y tabulaciones no serán interpretados""" 
  • string templates. Plantillas de cadenas de texto. En las que se pueden introducir expresiones (variables y operadores) que serán interpretados en tiempo de ejecución. Las expresiones deben ser señaladas con $. Y la cadena completa, la plantilla, con una arroba:

     @"$variable1 * $variable2 = $(a*b)" //"6 * 7 = 42" 

Además, es posible partir una cadena de caracteres utilizando la expresión [inicio:fin]. Donde inicio es la posición (incluyente) del primer carácter (empezando en 0) y fin es la posición (excluyente) del último carácter:

string saludo = "hola mundo";
string s1 = saludo[5:11]; // "mundo"

Se puede acceder a un carácter en concreto, teniendo en cuenta que se está utilizando, de forma predeterminada, la codificación UTF8:

unichar c = saludo[7];

Sin embargo, las cadenas de caracteres en Vala son inmutables. Esto significa que no se puede modificar directamente un carácter individual de una cadena. No son simples Arrays. La cadena tiene que ser procesada internamente ya que en UTF8 cada carácter puede ocupar diferentes cantidades de bytes.

Finalmente, decir que la mayoría de los tipos básicos disponen de métodos de conversión a, y desde, string:

bool b = "false".to_bool();
string s1 = true.to_string();
int i = "-52".to_int();
string s2 = 21.to_string();

Arrays

Se pueden definir Arrays de cualquier tipo. Ejemplo de Array unidimensional:

in[] a = new int[10];
int[] b = {2,5,6,1};

Ejemplo de Array multidimensional:

int[,] c = new int[3,4];
int[,] d = {{1,1},{2,2}};

Sólo si el array es local o privado, es posible añadir elementos dinámicamente. Y su tamaño se va incrementando en potencias de 2. Esto se hace con el operador '+=':

int[] e;
e += 12;
e += 5;

El atributo length muestra el número de elementos del array. Que no tiene porque corresponderse con su tamaño interno.

Es posible establecer el tamaño fijo del array en su declaración. Y en este caso no hace falta instanciar el tipo con el operador new():

int f[10];

Por lo visto, todavía no están soportados los arrays multidimensionales irregulares. Donde cada dimensión es de un tamaño diferente:

int[5][3];

Tipos dinámicos

También se pueden utilizar tipos dinámicos declarando las variables con var:

var a = 32;
var b = "hola";

Esto es muy útil para reducir la redundancia en el código. En java, por ejemplo, con la introducción de los tipos genéricos, tendríamos el siguiente código para la instanciación de una clase:

MiAlgo<string, MiOtro<string, int>> algo = new MiAlgo<string, MiOtro<string, int>>();

La misma instanciación podría haber quedado resuelta, utilizando tipos dinámicos, de la siguiente manera (tal como se hace en Groovy):

var algo = new MiAlgo<string, MiOtro<string, int>>();

Operadores

Operadores (separados por comas)

Descripción

=

Operador de asignación: asigna un valor a una variable.

+, -, /, *, %

Operadores aritméticos: suma, resta, división, multiplicación y módulo.

+=, -=, /=, *=, %=

Operadores aritméticos en los que a la izquierda debe haber un operando al que asignar el resultado.

++, --

Incremento y decremento del valor de una variable respectivamente.

|, ^, &, ~

Operadores de comparación a nivel de bit: or, or exclusivo, and y not.

|=, &=, ^=

Modificadores de bits en los que a la izquierda debe haber un operando al que asignar el resultado: or, or exclusivo, and y not.

<<, >>

Modificadores de bits: el resultado de mover hacia la izquierda y hacia la derecha, respectivamente, los bits de una variable. Tantas posiciones como indique el operando de la derecha.

<, >, ==

Operadores lógicos de comparación: menor, mayor e igualdad, respectivamente.

!, &&,

Operadores lógicos: not, and y or, respectivamente.

(expresión)?(valor en verdadero):(valor en falso)

Operador condicional ternario. Evalúa una condición y devuelve el resultado según si la expresión es verdadera o falsa.

??

Operador de prevención de nulo. Establece un valor predeterminado en caso de que una referencia sea nula. Por ejemplo: x = a??b Es equivalente a x = (a != null) ? a : b.

as

Operador de casting de tipo dinámico. Comprueba, en tiempo de ejecución, que el tipo sea correcto. En caso contrario se asigna un valor nulo. Por ejemplo:Button b = widget as Button es equivalente a Button b = (widget is Button) ? (Button) widget : null;.

=>

Expresión lambda para funciones anónimas.

while, do while, for, foreach, switch

Operadores de control.

Funciones

Los nombres de las funciones en Vala (también llamados métodos) siguen la convención de utilizar letras minúsculas y un guión bajo para separar palabras. Se utiliza el guión bajo en vez de la notación en camello porque es más coherente con los nombres de las funciones de las librerías de Vala y GObject.

No existe la sobreescritura de métodos. Esto significa que no pueden existir dos métodos con el mismo nombre aunque éstos tengan distintos parámetros. El motivo es que las funciones escritas en Vala tambén deberían ser usables por programadores de C.

Es posible establecer un valor predeterminado para el argumento de un método. Así se puede simular el uso, común en otros lenguajes como Java, de métodos con el mismo nombre y número creciente de argumentos.

Por ejemplo, en Vala:

void f(in x, string s="hola", double z = 0.5){...};

Serviría para hacer lo que en Java sería:

void f(int x, string s, double z){...};
void f(int x, string s) { f(x, s, 0.5}; }
void f(int x) { f(x, "hola"); }

Vala hace una comprobación básica de valores nulos en los argumentos y devoluciones de los métodos. Por este motivo hay que indicar qué argumentos pueden tener valor nulo. En el siguiente ejemplo, tanto el valor de retorno como los argumentos texto y objeto pueden tener un valor nulo:

string? nombre_funcion (string? texto, Clase? objeto, int entero)

Delegados

Existen tipos delegados (punteros a funciones). Así se pude pasar una función como parámetro a otra función. Por ejemplo:

//definir un tipo delegado
delegate void tipo_delegado(int a);
void funcion1 (int a){...}
void funcion2 (tipo_delegado d, int a){ d(a); }
...
        funcion2(funcion1, 5);

Documentacion/Desarrollo/Tutoriales/Vala (última edición 2010-07-15 20:52:32 efectuada por DavidHoces)