Sie sind auf Seite 1von 78

Tabela

de contedos
Introduo 1.1

O que vala? 1.1.1


Para quem este tutorial 1.1.2

Conveno 1.1.3

Primeiro programa 1.2


Compilao e execuo 1.2.1

Bsicos 1.3

Arquivos-fonte e compilao 1.3.1


Viso geral da sintaxe 1.3.2

Comentrios 1.3.3
Tipo de dados 1.3.4
Tipos valor 1.3.4.1

Strings 1.3.4.2
Arrays 1.3.4.3
Tipos referncia 1.3.4.4

Converso de tipo esttico 1.3.4.5


Tipagem por inferncia 1.3.4.6
Definindo novo tipo com base em outro 1.3.4.7

Operadores 1.3.5
Estruturas de controle 1.3.6
Elementos da linguagem 1.3.7

Mtodos 1.3.7.1
Delegaes 1.3.7.2

Mtodos annimos/Closures 1.3.7.3


Namespaces 1.3.7.4

Structs 1.3.7.5

Classes 1.3.7.6
Interfaces 1.3.7.7

Atributos de cdigo 1.3.8

Programao orientada a objetos 1.4


Bsicos 1.4.1

Contrutor 1.4.2

Destrutor 1.4.3
Sinais 1.4.4

Propriedades 1.4.5

Herana 1.4.6
Classes abstratas 1.4.7

Mtodos virtuais 1.4.7.1

Interfaces 1.4.8

2
Definindo pr-requisitos 1.4.8.1

Definindo padro de implementao em mtodos 1.4.8.2


Propriedades 1.4.8.3
Mixins e mtiplas heranas 1.4.8.4

Polimorfismo 1.4.9

Ocultao de Mtodos 1.4.10


Informao do tipo em tempo de execuo 1.4.11

Converso dinmica de tipo 1.4.12

Genricos 1.4.13
Construo estilo GObject 1.4.14

Recursos avanados 1.5

Programao de contrato e declarao 1.5.1

Tratamento de erro 1.5.2


Direo do parmetro 1.5.3
Colees 1.5.4

ArrayList 1.5.4.1
HashMap 1.5.4.2
HashSet 1.5.4.3

Read-Only Views 1.5.4.4


Mtodos com suporte de sintaxe 1.5.5
Multi-Threading 1.5.6

Threads em Vala 1.5.6.1


Controle de recurso 1.5.6.2
O lao principal 1.5.7

Mtodos asscronos 1.5.8


Modificador weak 1.5.9

Posse 1.5.10
Referncia no possuda 1.5.10.1

Mtodo de posse 1.5.10.2

Propriedade de posse 1.5.10.3


Transferncia de posse 1.5.10.4

Argumento Variable-Length 1.5.11

Ponteiros 1.5.12
Classes sem objeto 1.5.13

Integrao com D-Bus 1.5.14

Recursos experimentais 1.6


Relao encadeada 1.6.1

Expresso regular literal 1.6.2

Modo no-nulo rigoroso 1.6.3


Bibliotecas 1.7

Usando bibliotecas 1.7.1

Criando uma biblioteca 1.7.2

3
Compilao e comando de vinculao using 1.7.2.1

Construindo bibliotecas com VAPI 1.7.3


Ferramentas 1.8
valac 1.8.1

vapigen 1.8.2

4
Introduo

Tutorial de Vala

5
Introduo

6
O que vala?

O que Vala?
Vala uma linguagem de programao que habilita tcnicas modernas serem usadas para escrever aplicaes que
rodam na plataforma Gnome, particulamente Glib e GObject. Esta plataforma tem bastante tempo um ambiente de
programao completo, com certas caractersticas como um sistema de tipos dinmico e gerenciamento de memria
assistida. Antes de Vala, o nico caminho para programar para a plataforma era com a apis nativas da mquina c, que
expe com muita frequncia detalhes indesejados, com uma linguagem de alto nvel que tem um assistente de mquina
virtual, tais como as linguagens Python ou o Mono/c#, ou alternativamente, com c++ atravs de uma wrapper library.

Vala diferente de todas estas outras tcnicas, como suas sadas so cdigos gerados em C que podem ser compiladas
para executar sem a necessidade de suporte a bibliotecas extras alm da plataforma Gnome. Isto tem muitas
consequncias, porm mais importante:

Programas escritos em Vala devem ter performance amplamente similar daqueles escritos diretamente em C, sendo
mais fcil e rpido escrever e manter.
Uma aplicao em vala no pode fazer nada que no possa ser feito em C. Enquanto Vala introduz vrias
funcionalidades na linguagem que no esto acessveis em C, estas so todas mapeadas para contruo em C,
embora sejam frequentemente aquelas que so difceis ou muito demorado para escrever diretamente.

Assim sendo, enquanto Vala uma linguagem moderna com todos os recursos que voc esperaria, ela ganha seu poder
de uma plataforma existente, e deve de certa forma obedecer algumas regras por ela estabelecida.

7
Para quem este tutorial

Para quem este tutorial?


Este tutorial no ir entrar em profundidade sobre as prticas bsicas de programao. Ele ir apenas explicar
brevemente as prticas de programao orientado objetos, ao invs de focar em como Vala aplica os conceitos. Assim
sendo, ser til se voc j tm experincia de uma variedade de linguagens de programao, embora o conhecimento
aprofundado de qualquer uma linguagem em particular no seja necessrio.

Vala compartilha muitas sintaxes com C#, porm o tutorial ir tentar evitar descrever caractersticas em termos de
similaridades ou diferenas com C# ou Java, com o objetivo de faze-lo mais acessvel.

O que ser bem til uma compreeno razovel de C, ao passo que isso no seja necessrio para entender Vala.
importante perceber que programas em Vala so executados como C, e ir frequentemente interagir com biblitecas em C.
Ter uma compreenso razovel de C ir ajudar a criar um entendimento aprofundado em Vala mais facilmente.

8
Conveno

Convenes
O cdigo ser em texto monoespaado , e os comandos sero todos prefaciados com o caractere $ do prompt.

9
Primeiro programa

O primeiro programa

class Demo.OlaMundo : GLib.Object {

public static int main(string[] args) {

stdout.printf("Ol, Mundo\n");

return 0;
}
}

O respeitvel programa Ol mundo em Vala.

class Demo.OlaMundo : GLib.Object {

Essa linha identifica o comeo da definio da classe. As classes em Vala so muito similares em conceito com outras
linguagens. Uma classe basicamente um tipo de objeto, das quais as instancias podem ser criadas, todas tendo as
mesmas propriedades. A implementao de um tipo classificado feita pela biblioteca gobject, esses detalhes no so
importantes para uso geral.

O importante que essa classe especificamente descrita como sendo uma subclasse da GLib.Object. Isto porque a
Vala permite outros tipos de classe, mas nos casos gerais o tipo que voc quer. De fato, alguns recursos do Vala s so
permitidos se sua classe descendente de um Object, proveniente da GLib.

public static int main(string[] args) {

Esse o comeo da definio de um mtodo. Um mtodo uma funo relacionada a um tipo de objeto e que pode ser
executada num objeto daquele tipo. O mtodo esttico significa que esse mtodo pode ser chamado sem uma instancia
em particular. O fato do mtodo ser chamado main e ter a assinatura significa que o Vala vai reconhece-lo como o ponto
de entrada do programa.

O mtodo main no precisa ser definido dentro de uma classe. Porem, caso seja, precisa ser esttico. No importa se
pblico ou privado. O retorno pode ser inteiro(int) ou vazio(void). Com um retorno vazio(void) o programa vai terminar
implicitamente com o cdigo de retorno 0. O arranjo de caracteres para captura de argumentos de linha de comando
opcional.

stdout.printf("Ol, Mundo\n");

stdout um objeto no namespace GLib que certifica o Vala de que voc tem o acesso requerido. Essa linha instrui o Vala
a executar o mtodo chamado printf do objeto stdout, com uma string Ol, Mundo como argumento. No Vala, essa sempre
a sintaxe usada para chamar um mtodo num objeto, ou pra acessar os dados de um objeto. \n a sequencia de
escape para uma nova linha.

return 0;

A funo da palavra return de retornar um valor para quem chamou e terminar a execuo do mtodo main que
tmbem termina a execuo do programa. O valor retornado pelo mtodo main tido como cdigo de sada do programa.

A ultima linha finaliza as definies do mtodo e da classe.

10
Primeiro programa

11
Compilao e execuo

Compilar e executar
Assumindo que voc tem o Vala instalado, o que voc precisa fazer pra compilar e rodar o programa :

$ valac OlaMundo.vala
$ ./OlaMundo

valac o compilador Vala, o qual vai compilar o seu cdigo Vala em binrio. O binrio resultante vai ter o mesmo nome
que o cdigo fonte e pode ser executado diretamente na maquina. Voc provavelmente j imaginar a sada do programa.

12
Bsicos

13
Arquivos-fonte e compilao

Arquivos-fonte e compilao
Cdigo vala escrito em arquivos com exteno .vala. Ele no refora a estrutura tanto quanto linguagens como Java -
no existem conceitos de pacotes ou classes nos arquivos. Invs disso a estrutura definida pelo texto dentro de cada
arquivo, descrevendo a localizao lgica do cdigo com construtores como namespaces. Quando voc quer compilar
cdigo Vala, voc descreve ao compilador uma lista de arquivos requeridos, e Vala entende como eles se encaixam.

A vantagem disso que voc pode por quantas classes ou funes voc quiser dentro do arquivo, at combinando partes
de diferentes namespaces juntas. Isso no necessriamente uma boa ideia. Existem certas convenes que voc
provavelmente quer seguir. Um bom exemplo de como estruturar um projeto em Vala o prprio projeto Vala.

Todos os arquivos fonte para o pacote so supridos como parmetros da linha de comando para o compilador Vala
valac , junto com as bandeiras(flags) do compilador. Por exemplo:

$ valac compiler.vala --pkg libvala

ir produzir um binrio com o nome compiler que vincula com o pacote libvala. De fato, como o compilador valac
produzido!

Se voc quer que o binrio tenha um nome diferente ou se voc passou multiplos arquivos fonte ao compilador voc pode
especificar o nome do executvel explicitamente com o parmetro -o :

$ valac source1.vala source2.vala -o meuprograma


$ ./meuprograma

Se voc passar o parmetro -C ao valac, ele no compilar seu programa em arquivo binrio. Invs disso a sada ser o
cdigo C para cada cdigo fonte Vala correspondente, nesse caso source1.c e source2.c. Se voc olhar o conteudo
desses arquivo voc pode ver programar uma classe em Vala equivalente a mesma tarefa em C, porm bem mais
sucinto. Voc vai tambm perceber que essa classe registrada dinamicamente na execuo. Isso um bom exemplo do
poder da plataforma GNOME, mas como foi dito antes, voc no precisa saber sobre isso para usar Vala.

Se voc quer ter um arquivo header em C para o seu projeto voc pode usar o parmetro -H :

$ valac ola.vala -C -H ola.h

14
Viso geral da sintaxe

Viso geral da sintaxe


A sintaxe do Vala uma sntese de C# e Java. Como resultado, a maioria disso ser familiar para programadores que
conhecem alguma linguagem parecida com C.

O escopo definido usando chaves). Um objeto ou referncia s vlido entre { e } . Estes so tambm os
delimitadores usados para definir classes, mtodos, blocos de cdigo, etc, ento eles automaticamente tm seus prrpios
escopos. Vala no estrita sobre aonde as vriaveis so declaradas.

Um identificador definido pelo tipo e nome, ex. int c significa um inteiro chamado c. No caso dos tipos valor isso
tambm cria um objeto de dado tipo. Para tipos referncia esses tipos apenas definem uma nova referencia que
inicialmente no aponta a lugar nenhum.

Nomes de identificadores podem ser qualquer combinao de letras ([a-z], [A-Z]), sublinha e dgitos. Todavia, para definir
ou referir a um identificador com um nome que comea com um digito ou uma palavra-chave, voc deve prefixar com um
caractere @ . Esse caractere no considerado parte do nome. Por exemplo voc pode nomear um mtodo foreach
escrevendo @foreach , mesmo sendo uma palavra-chave reservada do Vala. Voc pode omitir o caractere @ quando for
interpretado como um nome de identificador inequivocamente, como em foo.foreach() .

Tipos referencia so instanciados usando o operador new e o nome de um mtodo de construo, o qual usualmente o
nome do tipo, ex. Object o = new Object() cria um novo Object e faz o uma referncia a ele.

15
Comentrios

Comentrios
Vala permite que comentrios sejam registrados no cdigo de diferentes formas.

// O comentrio continua at o final da linha

/* O comentrio dura entre os delimitadores */

/**
* Comentrio de documentao
*/

Esses so manipulados da mesma forma que na maioria das outras linguagens e ento precisa de pouca explicao. Os
comentrios de documentao no so especiais para Vala, mas uma ferramenta de gerao de documentao como o
Valadoc ir reconhece-los.

16
Tipo de dados

Data Types
Falando amplamente existem dois tipos de dado em Vala: tipos referencia e tipos valor. Esses nomes descrevem como
instancias dos tipos so passadas pelo sistema - Um tipo valor copiado quando designada para um novo identificador,
um tipo referencia no copiada, invs disso o novo identificador simplesmente uma nova referencia para o mesmo
objeto.

Uma constante definida colocando const antes do tipo. A conveno de nome das constante TUDO_EM_CAIXA_ALTA .

17
Tipos valor

Tipos valor
Vala suporta uma variedade de tipos simples como a maioria das outras linguagens fazem.

Byte, char , uchar ; seus nomes so char por motivos histricos.


Character, unichar ; um carcter Unicode 32-bit
Integer, int , uint
Long Integer, long , ulong
Short Integer, short , ushort
Guaranteed-size Integer, int8 , int16 , int32 , int64 assim como seus respectivos no sinalizados uint8 ,
uint16 , uint32 , uint64 . O nmero indica o tamanho em bits.

Float number, float , double


Boolean, bool ; possveis valores so true e false
Compound, struct
Enumeration, enum ; representada por valores inteiros, no classes como os enums de Java

Aqui temos alguns exemplos.

/* tipos atmicos */
unichar c = 'u';
float percentile = 0.75f;
const double MU_BOHR = 927.400915E-26;
bool the_box_has_crashed = false;

/* definindo um struct */
struct Vector {
public double x;
public double y;
public double z;
}

/* definindo um enum */
enum WindowType {
TOPLEVEL,
POPUP
}

A maioria desses tipos podem ter tamanhos diferentes em plataformas diferentes, com exceo dos tipos guaranteed-size
integer(Inteiros de tamanho garantido). O operador sizeof retorna o tamanho que varivel de um dado tipo ocupa em
bytes:

ulong nbytes = sizeof(int32); // nbytes ser 4 (= 32 bits)

Voc pode determinar os valores mximos e mnimos de um tpo numrico com .MIN e .MAX, ex. 'int.MIN' e int.MAX .

18
Strings

Strings(Conjuntos de caracteres)
O tipo de dados para strings(conjuntos de caracteres) string . As strings em Vala so codificadas em UTF-8 e
imutveis.

string texto = "Um conjunto de caracteres";

Vala oferece um recurso chamado verbatim strings. Strings quais as sequencias de escape (como o \n ) no so
interpretadas, quebras de linhas sero preservadas e sinais de citao no precisam ser mascarados. Elas so cercadas
com trs sinais de citao. Possveis identaes aps uma quebra de linha so parte da string tambm.

string verbatim = """Essa uma to falada "verbatim string". Verbatim strings no processam sequncias de escape, co
mo \n, \t, \\, etc. Elas podem conter citaes e abranger mltiplas linhas.""";

Strings prefixadas com '@' so templates de string. Elas podem evaluate variveis embutidas e expresses prefixadas
com '$':

int a = 6, b = 7;
string s = @"$a * $b = $(a * b)"; // => "6 * 7 = 42"

Os operadores de igualdade == e != comparam o contedo das duas strings, contrario ao comportamento do Java que
nesse caso checaria a igualdade referencial.

Voc pode recortar uma string com [inicio:fim] . Valores negativos representam posies relativas ao fim da string:

string greeting = "hello, world";


string s1 = greeting[7:12]; // => "world"
string s2 = greeting[-4:-2]; // => "or"

Note que os ndices em Vala comeam com 0 como na maioria das outras linguagens de programao. Apartir do Vala
0.11 voc pode acessar um nico byte de uma string com [ndice] :

uint8 b = greeting[7]; // => 0x77

Porem, voc no pode designar um novo valor em byte para essa posio, uma vez que as strings em Vala so imutveis.

Muitos dos tipos bsicos tem mtodos razoveis para anlisar e converter para strings, por exemplo:

bool b = bool.parse("false"); // => false


int i = int.parse("-52"); // => -52
double d = double.parse("6.67428E-11"); // => 6.67428E-11
string s1 = true.to_string(); // => "true"
string s2 = 21.to_string(); // => "21"

Dois mtodos teis para escrever e ler strings de/para o console (e para suas primeiras exploraes com Vala) so
stdout.printf() e stdin.read_line():

stdout.printf("Hello, world\n");
stdout.printf("%d %g %s\n", 42, 3.1415, "Vala");
string input = stdin.read_line();
int number = int.parse(stdin.read_line());

Voc j conhece o stdout.printf() pelo exemplo do Ol mundo.

19
Strings

Atualmente, ele pode receber um nmero arbitrrio de argumentos de tipos diferentes, no qual o primeiro argumento
uma format string, seguindo as mesmas regras das strings no formato do C.

Se voc precisa emitir uma mensagem de erro voc pode usar o stderr.printf() invs do stdout.printf().

Em adio o operador in pode ser usado para determinar quando uma string contm outra, ex.

if ("ere" in "Able was I ere I saw Elba.") ...

Para mais informaes, veja uma viso completa da classe string.

Um programa exemplo demostrando o uso de uma string tambm est disponvel.

20
Arrays

Arrays (Arranjos/Vetores)
Um array declarado dando o tipo seguido por [] e criado usando o operador new ex. int[] a = new int[10] para
criar um arranjo de nmeros inteiros(integer). O tamanho do array pode ser obtido pela varivel membro(atributo) length
ex. int count = a.length . Note que se voc escrever Object[] a = new Object[10] nenhum objeto vai ser criado, s o
array pra armazenar-los.

int[] a = new int[10];


int[] b = { 2, 4, 6, 8 };

Voc pode cortar um array com [comeo:fim] :

int[] c = b[1:3]; // => { 4, 6 }

Cortando um array vai resultar numa referencia para o dado requerido, no uma cpia. Porem, designando um recorte
para uma varivel owned (como feito abaixo) vai resultar em uma cpia. Se voc quer evitar uma copia, voc precisa
designar o recorte a um array unowned ou passar diretamente para um argumento (argumentos so, por definio, no
prprios):

unowned int[] c = b[1:3]; // => { 4, 6 }

Arrays Multi-dimensionais so definidos com [,] ou [,,] etc.

int[,] c = new int[3,4];


int[,] d = {{2, 4, 6, 8},
{3, 5, 7, 9},
{1, 3, 5, 7}};
d[2,3] = 42;

Esse tipo de array representado por um nico bloco de memria contguo. Arrays multi-dimensionais irregulares ( [][] ,
tambm conhecido como "arranjos empilhados/arrays empilhados"), aonde cada linha pode ter um tamanho diferente,
ainda no so suportados.

Para encontrar o tamanho de cada dimeno em um array multi-dimensional, o membro length vira um array,
armazenando o tamanho de cada respectiva dimenso.

int[,] arr = new int[4,5];


int r = arr.length[0];
int c = arr.length[1];

Por favor note que voc no pode obter um array mono-dimensional de um array multidimensional, nem mesmo recortar
um array multidimensional:

int[,] arr = {{1,2},


{3,4}};
int[] b = arr[0]; // no vai funcionar int[] c = arr[0,]; // no vai funcionar int[] d = arr[:,0]; // no vai func
ionar int[] e = arr[0:1,0]; // no vai funcionar int[,] f = arr[0:1,0:1]; // no vai funcionar

Voc pode inserir elementos dinamicamente no array com o operador += . Todavia, isso s funciona para arrays locais ou
privados. O array automaticamente realocado se for necessrio. Internamente essa realocao acontece com os
tamanhos crescendo em potencia de 2 pela eficincia de tempo de execuo. Porem, .length guarda o numero atual de
elementos, no o tamanho interno.

21
Arrays

int[] e = {};
e += 12;
e += 5;
e += 37;

Voc pode redimensionar um array chamando resize() nele. Isso vai manter o contedo original(o quanto couber).

int[] a = new int[5];


a.resize(12);

Voc pode mover elementos dentro do array chamando move(src, dest, length) nele. A posio original vai ser preenchida
com 0.

uint8[] chars = "hello world".data;


chars.move (6, 0, 5);
print ((string) chars); // "world "

Se voc colocar os colchetes quadrados aps o indentificador junto com um indicador do tamanho voc vai ter um array
de tamanho fixo. Arrays com tamanho fixo so alocados no stack (se usado como varivel local) ou alocado in-line (se
usado como campo) e voc no pode os realocar depois.

int f[10]; // no 'new ...'

Vala no faz nenhuma verificao de limite do acesso dos arrays na execuo. Se voc precisa de mais segurana deve
usar uma estrutura de dados mais sofisticada como um ArrayList. Voc vai aprender mais sobre isso depois na sesso
sobre coleces.

22
Tipos referncia

Tipo Referncia
Os tipos referencias so todos os tipos declarados como uma classe, independente de ser descendente de um objeto
Glib(Object). Vala vai assegurar que quando voc passar um objeto por referencia o sistema guardar o nmeros de
referencias ativas para gerenciar a memoria para voc. O valor de uma referencia que no aponta para lugar nenhum
null . Mais sobre classes e seus recursos na sesso sobre programao orientada a objetos.

/* definindo uma classe */


class Track : GLib.Object { /* herdando de 'GLib.Object' */
public double mass; /* um campo pblico */
public double name { get; set; } /* uma propriedade pblica */
private bool terminated = false; /* um campo privado */
public void terminate() { /* um mtodo pblico */
terminated = true;
}
}

23
Converso de tipo esttico

Converso esttica de tipo


Em Vala, voc pode fazer casting(converso) de uma varivel de um tipo para outro. Para uma converso esttica, uma
varivel convertida pelo nome desejado entre parenteses. Uma converso esttica no impe nenhuma checagem de
segurana do tipo no tempo de execuo. Isso funciona para todos os tipos do Vala. Por exemplo,

int i = 10;
float j = (float) i;

Vala suporta outro mecanismo de converso chamado dynamic casting(converso dinmica) que faz checagem de tipo no
tempo de execuo e descrito na sesso sobre programao orientada a objetos.

24
Tipagem por inferncia

Inferncia de tipos
Vala has a mechanism called type inference, whereby a local variable may be defined using var instead of giving a type,
so long as it is unambiguous what type is meant. The type is inferred from the right hand side of the assignment. It helps
reduce unnecessary redundancy in your code without sacrificing static typing:

Vala tem um mecanismo chamado type inference(inferncia de tipo), na qual uma varivel local pode ser definida usando
var invs de determinar um tipo, enquanto no for ambguo que tipo pretendido. O tipo inferido pelo lado direito da

designao. Isso ajuda a reduzir uma redundncia desnecessria no seu cdigo sem sacrificar a tipagem esttica.

var p = new Pessoa(); // same as: Pessoa p = new Pessoa();


var s = "ol"; // mesmo que: string s = "ol";
var l = new List<int>(); // mesmo que: List<int> l = new List<int>();
var i = 10; // mesmo que: int i = 10;

Isso funciona apenas para variveis locais. Inferncia de tipo especialmente til para tipos com argumentos de tipo
genrico (mais disso depois). Compare

MyFoo<string, MyBar<string, int>> foo = new MyFoo<string, MyBar<string, int>>();

vs.

var foo = new MyFoo<string, MyBar<string, int>>();

25
Definindo novo tipo com base em outro

Definindo um tipo novo a partir de outro


Definindo um tipo novo questo de derivar de um que voc precisa.

/* definindo um apelido para um tipo bsico (equivalente ao typedef int Integer em C)*/
[[SimpleType](/SimpleType)] public struct Integer : uint { }

/* Define um novo tipo de um container como GLib.List com elementos do tipo GLib.Value */
public class ValueList : GLib.List<GLib.Value> {

[CCode (has_construct_function = false)]


protected ValueList ();
public static GLib.Type get_type ();
}

26
Operadores

Operadores
=

atribuio. O operando esquerdo deve ser um identificador, e o direito deve resultar em um valor ou referncia
apropriadamente.

+, -, /, *, %

aritimtica bsica, aplicada aos operandos esquerdo e direito. O operador + tambm pode concatenar strings.

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

operao aritimtica entre o operador esquerdo e direito, where the left must be an identifier, para qual o resultado
atribudo.

++, --

operaes de incremento e decremento com atribuio implicita. Esses tomam s um argumento, que deve ser um
identificador de um tipo simples de dado.

O valor ser mudado e atribuido de volta ao identificador. Esses operadores podem ser dispostos como prefixo ou
psfixos, - com o primeiro o valor calculado da declarao ser o valor recm calculado, com o ltimo o valor original
retornado.

|, ^, &, ~, |=, &=, ^=

operaes bitwise: or(ou), exclusive or(ou exclusivo), and(e), not(no). O segundo conjunto inclui atribuio e anlogo s
verses aritimticas. Eles podem ser aplicadas a qualquer tipo valor simples. (No existe operador de atribuio associado
com ~ porque esse o operador unrio. A operao equivalente a = ~a ).

<<, >>

operaes bit shift, desloca o operando esquerdo o nmero de bits de acordo com o operando direito.

<<=, >>=

operaes bit shift, desloca o operando esquerdo o numero de bits de acordo com o operando direito. O operando
esquerdo deve ser um identificador, o qual o resultado atribudo.

==

teste de igualdade. Resulta em um valor booleano(bool) dependendo se os operandos esquerdo e direito so iguais. No
caso dos tipos valor isso significa que seus valores so iguais, no caso dos tipos referencia que os objetos so da mesma
instncia. Uma exceo a essa regra o tipo string , que testada em igualdade por valor.

<, >, >=, <=, !=

27
Operadores

teste de inigualdade. Resulta em um valor bool dependendo se os operandos esquerdo e direito so diferentes na
maneira descrita. Eles so vlidos para valores simples de dados, e para o tipo string . Para strings esses operadores
comparam a ordem lexogrfica.

!, &&, ||

operadores lgicos: not(no), and(e), or(ou). Essas operaes podem ser aplicadas a valores booleanos - o primeiro toma
um valor dos outros dois.

? :

operador de condio ternria. Resulta em uma condio e retorna a sub-expresso da esquerde ou direita baseado e,
qual condio verdadeira ou falsa: condio ? valor se for verdade : valor se for falso

??

operador null coalescing: a ?? b equivalente a a != null ? a : b . Esse operador til para prover um valor padro no
caso da referncia ser nula(null):

stdout.printf("Ol, %s!\n", nome ?? "pessoa desconhecida");

in

checa se o operando direito contem o operando esquerdo. Esse operador funciona em arrays, strings, colees ou
qualquer outro tipo que possua o mtodo contains(). Para strings ele executa uma busca de substring.

Operadores no podem ser sobrecarregados em Vala. Existem operadores extras que so vlidos no contexto de
expresses lambda e outras tarefas especficas - estes so explicados no contexto onde so aplicveis.

28
Estruturas de controle

Estruturas de controle
while (a > b) { a--; }

vai diminuir a repetidamente, checando antes de cada iterao que a maior que b.

do { a--; } while (a > b);

vai diminuir a repetidamente, checando aps cada iterao que a maior que b.

for (int a = 0; a < 10; a++) { stdout.printf("%d\n", a); }

vai inicializar a em 0, ento imprimir a repetidamente at a deixar de ser menor que 10, incrementando a aps cada
iterao.

foreach (int a in int_array) { stdout.printf("%d\n", a); }

vai imprimir cada inteiro num array, ou outra coleo itervel. O significado de "itervel" vai ser descrito depois.

Todos os quatro tipos precedentes de repetio(loop) podem ser controlados com as palavras-chave break e continue .
Uma instruo break faz a repetio terminar imediatamente, enquanto continue ir pular direto para o teste da
iterao.

if (a > 0) { stdout.printf("a is greater than 0\n"); }


else if (a < 0) { stdout.printf("a is less than 0\n"); }
else { stdout.printf("a is equal to 0\n"); }

executa uma parte do cdigo baseada no conjunto de condies. A primeira condio decide que cdigo ser executado,
se a maior que 0 ele no testar se menor que 0. Qualquer numero de blocos else if permitido, e zero ou um bloco
else.

switch (a) {
case 1:
stdout.printf("one\n");
break;
case 2:
case 3:
stdout.printf("two or three\n");
break;
default:
stdout.printf("unknown\n");
break;
}

Uma declarao switch executa exatamente uma ou zero sees do cdigo com base no valor passado. Em Vala no
existe queda(fall through) nos os casos(cases), exceto nos casos vazios. Para assegurar isto, cada caso no-vazio deve
finalizar com uma declarao break , return ou throw . possvel usar uma declarao switch com strings.

Uma nota para programadores C: condies sempre devem ser um valor booleano. Isso significa que se voc quer checar
uma varivel null ou 0 voc precisa fazer isso explicitamente:

if (object != null) { } or if (number != 0) { } .

29
Estruturas de controle

30
Elementos da linguagem

Elementos da linguagem

31
Mtodos

Mtodos
Funes so chamadas mtodos em Vala, independente de serem definidos dentro ou fora de uma classe. A partir de
agora ns irmos chama-las pelo termo mtodo.

int mtodo_nome(int arg1, Object arg2) {


return 1;
}

Esse cdigo define um mtodo, tendo o nome mtodo_nome, recebendo dois argumentos, um inteiro e outro Objeto (O
primeiro passado por valor, o segundo por referncia como descrito). O mtodo retornar um inteiro, que no caso 1.

Todos mtodos Vala so funes C, e portanto recbem um nmero arbitrrio de argumentos e retornam um valor (ou
nenhum se o mtodo declarado void(vazio)). Eles podem retornar mais valores aproximados caso sejam postos dados
em lugares conhecidos ao cdigo chamado. Detalhes de como fazer isso esto na seo "Direes dos parmetros" na
parte avanada desse tutorial.

A nomenclatura convncional para mtodos em Vala tudo_em_caixa_baixa com sublinhas separando palavras. Isso
pode ser um pouco desconhecido para programadores Java ou C# que esto acostumado com nome de mtodos em
CamelCase ou camelCaseMesclado. Mas com esse estilo voc vai ser consistente com outras bibliotecas Vala e
C/GObject.

No possvel ter mltiplos mtodos com o mesmo nome mas diferentes assinaturas dentro do mesmo
escopo(sobrecarga de mtodos):

void draw(string text) { }


void draw(Shape shape) { } // no possvel

Isso se deve ao fato de que bibliotecas produzidas em Vala tem preteno de serem usaveis por programadores C
tambm. Invs disso voc pode fazer algo assim em Vala:

void draw_text(string text) { }


void draw_shape(Shape shape) { }

Por escolher um nome diferente voc pode evitar um conflito de nomes. Em linguagens que suportam sobrecarga de
mtodos usada geralmente para prover mtodos convenientes com menos parmetros para encadear os mtodos mais
comuns:

void f(int x, string s, double z) { }


void f(int x, string s) { f(x, s, 0.5); } // no possvel
void f(int x) { f(x, "hello"); } // no possvel

Nesse caso voc pode usar o recurso argumento padro do Vala para parmetros dos mtodos para alcanar um
comportamento similar com um nico mtodo. Voc pode definir valores padres para os ltimos parmetros de um
mtodo, para que voc no precise passa-los explicitamente para uma chamada de mtodo:

void f(int x, string s = "ol", double z = 0.5) { }

Algumas chamadas possveis para esse mtodo podem ser:

f(2);
f(2, "oi");
f(2, "oi", 0.75);

32
Mtodos

possvel at definir mtodos com a quantidade de vriaveis como argumento (varargs) como o stdout.printf(), entretanto
no necessriamente recomentado. Voc aprender como fazer isso depois.

Vala performa um teste bsico de nulidade nos parmetros dos mtodos e nos valores de retorno. Se permitido que um
parmetro ou um retorno seja null , o tipo deve ser psfixado com um modificador ? . Essa informao extra ajuda o
compilador a executar checagens estticas e a adicionar afirmaes no tempo de execuo a cerca das pr-condies
dos mtodos, os quais podem ajudar a evitar problemas relacionados a erros como derefernciao de uma referncia
nula(null).

string? nome_do_metodo(string? texto, Foo? foo, Bar bar) {


// ...
}

Nesse exemplo texto , foo e o retorno podem ser null , entretanto, bar no pode ser null .

33
Delegaes

Delegaes
delegate void DelegateType(int a);

Delegaes representam mtodos, permitindo pedaos de cdigo serem passados como objetos. O exemplo acima define
um novo tipo chamado DelegateType no qual representa mtodos recebendo um int e no retornando valor. Qualquer
mtodo que se encaixe nessa assinatura pode ser atribudo uma vriavel do tipo ou passada como um argumento do
mtodo desse tipo.

delegate void DelegateType(int a);

void f1(int a) {
stdout.printf("%d\n", a);
}

void f2(DelegateType d, int a) {


d(a); // Chamando uma delegaao
}

void main() {
f2(f1, 5); // Passando um mtodo como argumento de delegao outro mtodo
}

Esse cdigo executar o mtodo f2, passando por referencia o mtodo f1 e o nmero 5. f2 ento executar o mtodo f1,
passando o nmero.

Delegaes podem ser criadas localmente tambm. O mtodo membro tambm pode ser designado uma delegao, ex.

class Foo {

public void f1(int a) {


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

delegate void DelegateType(int a);

public static int main(string[] args) {


Foo foo = new Foo();
DelegateType d1 = foo.f1;
d1(10);
return 0;
}
}

34
Mtodos annimos/Closures

Mtodos annimos/Closures
(a) => { stdout.printf("%d\n", a); }

Um mtodo annimo, tmbem conhecido como uma expresso lambda, funo literal ou closure, pode ser definida em
Vala com o operador => . A lista de parmetros fica a esquerda do operador, e o escopo do mtodo direita.

Um mtodo annimo por si s como como acima no faz muito sentido. Ele s til se designado diretamente a vriavel
de um tipo delegado ou passado como um argumento outro mtodo.

Tenha em mente que nem o parmetro nem o tipo de retorno informado explicitamente. Invs disso os tipos so inferidos
pela assinatura da delegao usada.

Atribuindo um mtodo annimo para uma varivel delegada:

delegate void PrintIntFunc(int a);

void main() {
PrintIntFunc p1 = (a) => { stdout.printf("%d\n", a); };
p1(10);

// Chaves so opcionais se o corpo conter s uma declarao:


PrintIntFunc p2 = (a) => stdout.printf("%d\n", a);
p2(20);
}

Passando um mtodo annimo para outro mtodo:

delegate int Comparator(int a, int b);

void my_sorting_algorithm(int[] data, Comparator compare) {


// ... 'compare' chamado em algum lugar aqui ...
}

void main() {
int[] data = { 3, 9, 2, 7, 5 };
// Um mtodo annimo passado como um segundo argumento:
my_sorting_algorithm(data, (a, b) => {
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
}

Mtodos annimos so closures) reais. Isso significa que voc pode acessar variveis locais de um mtodo exterior dentro
da expresso lambda:

delegate int IntOperation(int i);

IntOperation curried_add(int a) {
return (b) => a + b; // 'a' uma vriavel externa
}

void main() {
stdout.printf("2 + 4 = %d\n", curried_add(2)(4));
}

Nesse de adio com currying(veja Currying) retorna um mtodo recm criado que preserva o valor de a. Esse mtodo
retornado chamado diretamente depois com 4 como argumento resultante na soma de dois nmeros.

35
Mtodos annimos/Closures

36
Namespaces

Namespaces
namespace NameSpaceName {
// ...
}

Tudo entre as chaves dessa declarao est no namespace NameSpaceName e precisa ser refernciada como tal.
Qualquer cdigo fora desse namespace deve usar nomes qualificados para qualquer coisa dentro do nome do
namespace, ou estar em um arquivo com a declarao using para importar esse namespace:

using NameSpaceName;

// ...

Por exemplo, se o namespace Gtk importado com using Gtk; voc pode escrever Window invs de Gtk.Window. Um
nome completamente qualificado poder ser necessrio apenas em casos de ambiguidade, por exemplo entre GLib.Object
e Gtk.Object.

O namespace GLib importado por padro. Imagine uma linha invsivel using GLib; no nicio de cada arquivo Vala.

Qualquer coisa que voc no colocar em um namespace separado vai incorporar um namespace annimo global. Se voc
precisa referenciar o namespace global explicitamente devido a ambiguidade voc pode fazer isso com o prefixo
global:: .

Namespaces podem ser encadeados, tanto encadeando uma declarao dentro de outra quanto por dar um name na
forma Namespace1.NameSpace2.

Diversos outros tipos de definies podem declarar estar dentro de um namespace seguindo a mesma conveno de
nomenclatura, ex.

class NameSpace1.Teste { ... } . Note que fazendo isso, o namespace da definio ser o da declarao encadeada mais

os namespaces declarados na definio.

37
Structs

Structs
struct NomeStruct {
public int a;
}

define um tipo struct , ex. um tipo valor composto. Uma struct Vala pode ter mtodos de uma forma limitada e tambm
pode ter membros privados, de tal forma que o modificador de acesso public requirido explicitamente.

struct Cor {
public double vermelho;
public double verde;
public double azul;
}

assim que voc pode inicializar uma struct:

// sem inferncia de tipos Cor c1 = Cor();


Cor c2 = { 0.5, 0.5, 1.0 };
Cor c3 = Cor() {
red = 0.5,
green = 0.5,
blue = 1.0
};

// com inferncia de tipo var c4 = Cor();


var c5 = Color() {
red = 0.5,
green = 0.5,
blue = 1.0
};

Structs so alocados no stack/inline e copiados na atribuio.

Para definir um array de structs:

38
Classes

Classes
class ClassName : SuperClassName, InterfaceName {
}

define uma classe, ex. um tipo referncia. Em contraste com os structs, instncias de classes so alocadas no heap.
Existe muito mais sintaxes relacionada as classes, as quais sero mais discutidas integralmente em sees sobre
programao orientada a objetos.

39
Interfaces

Interfaces
interface InterfaceName : SuperInterfaceName {
}

define uma interface, ex. um tipo no instnciavel. Para criar uma instncia de uma interface voc deve primeiro
implementar seus mtodos abstratos em uma class no-abstrata. As interfaces do Vala so mais poderosas que em Java
ou C#. De fato, elas podem ser usadas como mixins(em ingls). Os detalhes das interfaces so descritos na seo de
orientao a objetos.

40
Atributos de cdigo

Atributos de cdigo
Atributos de cdigos instruem ao compilador Vala detalhes de como o cdigo deve funcionar na plataforma desejada. Sua
sintaxe [NomeDoAtributo] ou [NomeDoAtributo(param1 = valor1, param2 = valor2, ...)] .

Eles so usados mais usados para bindings nos arquivos vapi, [CCode(...)] sendo o atributo mais proeminente aqui.

Outro exemplo o atributo [DBus(...)] para exportar interfaces remotas pelo D-Bus

41
Programao orientada a objetos

Programao orientada a objetos


Mesmo Vala no forando voc a trabalhar com objetos, alguns recursos no so disponiveis de outra forma. Sendo
assim, voc certamente vai querer programar programar em um estilo orientado a objetos na maioria do tempo. Como na
maioria das linguagens atuais, com o objetivo de definir seus prprio objetos, voc vai escrever uma definio de classe.

Uma definio de classe dita que tipo de dado cada objeto de seu tipo possi, quais outros objetos ele tem referncia, e
quais mtodos podem ser executados nela. Uma definio pode incluir o nome de outra classe a qual a nova deve ser
uma subclasse. A instancia de uma classe tambm uma instancia de todas as super classes da classe, por ela derivar
todos os mtodos e dados, entretanto ela pode no ser capaz de acessar toda a super classe. Uma classe pode tambm
implementar qualquer quantidade de interfaces, quais so um conjunto de definies de mtodos que devem ser
implementados pela classe - uma instancia de uma classe tambm uma instancia de cada interface implementada por
sua classe ou super classe.

Classes em Vala podem tambm ter membros estticos. Esse modificador permite que qualquer dado ou mtodo seja
pertencente a classe como um todo, invs de ser especifica de sua instancia. Tais membros podem ser acessados sem a
posse de uma instancia de uma classe.

42
Bsicos

Bsicos
Uma simples classe pode ser definida como a seguir:

public class TestClass : GLib.Object {

/* Fields */
public int first_data = 0;
private int second_data;

/* Constructor */
public TestClass() {
this.second_data = 5;
}

/* Method */
public int method_1() {
stdout.printf("private data: %d", this.second_data);
return this.second_data;
}
}

Esse cdigo vai definir um novo tipo (que ser registrado automaticamente com o sistema de tipos da biblioteca gobject)
que contem trs membros. Existem tambm dois membros dado, um inteiro definido no comeo, e um mtodo chamado
method\1, que retorna uma integer. A declarao de classe dita que essa classe uma subclasse de GLib.Object, e
portanto instncias dela tambm so Objects, e contm tambm todos os membros desse tipo. O fato dessa classe
descender do GObject tambm significa que existem recursos especiais em Vala que podem ser usados para acessar
fcilmente alguns recursos do Object.

Essa classe descita como public (por padro, classes so internal ). A implicao disso que pode ser referenciada
diretamente pelo cdigo de fora do arquivo - se voc um programador C da glib/gobject, voc vai reconhecer isso como
sendo equivalente a definir interfaces de classes em um header que outro cdigo pode incluir.

Esses membros tambm so descritos como public ou private , pblico e privado respectivamente. O membro
first_data public , ento visvel diretamente para qualquer usuario da classe, e pode ser modificado sem conter uma
instncia estando ciente disso. O segundo dado membro private , sendo assim s pode ser referenciado por um cdigo
pertencente a esta classe. Vala suporta quatro modificadores de acesso diferentes:

Modificador Descrio

public Sem restries de acesso

private
Acesso limitado a definio da classe/estrutura(struct). Esse o padro se nenhum modificador
de acesso especificado.

protected Acesso limitado a definio da classe e qualquer classe que herde dela

internal Accesso limitado a classes definidas dentro do mesmo pacote

O construtor incializa uma nova instncia da classe. Ele tem o mesmo nome da classe, pode ter zero ou mais argumentos
e definido sem tipo de retorno.

A parte final dessa classe uma definio de mtodo. Esse mtodo chamado method\1, e retornar um inteiro. Como
esse mtodo no esttico, ele s pode ser executado numa instncia dessa classe, e pode acessar membros da
instncia. Ele pode fazer isso pela referncia this , que sempre aponta para a instncia em que o mtodo chamado. A
no ser que exista ambiguidade, o identificador this pode ser omitido se desejado.

Voc pode usar essa nova classe da forma seguir:

43
Bsicos

TestClass t = new TestClass();


t.first_data = 5;
t.method_1();

44
Contrutor

Contrutor
Vala suporta dois construtores de esquemas levemente diferentes: o estilo de construo do estilo Java/C# qual iremos
focar agora, e o estilo GObject que ser descrito na seo no final do captulo.

Vala no suporta sobrecarga de construtores pela mesma razo que sobrecarga de mtodos no permitida, o que
significa que uma classe no pode ter mltiplos construtores com o mesmo nome. Porm, isso no um problema porque
Vala suporta construtores nomeados. Se voc quer oferecer mltiplos construtores voc pode dar diferentes nomes
adicionais:

public class Button : Object {

public Button() {
}

public Button.with_label(string label) {


}

public Button.from_stock(string stock_id) {


}
}

A nicializao anloga:

new Button();
new Button.with_label("Click me");
new Button.from_stock(Gtk.STOCK_OK);

Voc pode encadear construtores pelo this() ou this. nome_exteno():

public class Point : Object {


public double x;
public double y;

public Point(double x, double y) {


this.x = x;
this.y = y;
}

public Point.rectangular(double x, double y) {


this(x, y);
}

public Point.polar(double radius, double angle) {


this.rectangular(radius * Math.cos(angle), radius * Math.sin(angle));
}
}

void main() {
var p1 = new Point.rectangular(5.7, 1.2);
var p2 = new Point.polar(5.7, 1.2);
}

45
Destrutor

Destrutor
Mesmo Vala gerenciando a memria por voc, voc pode necessitar do seu prprio destrutor caso decida fazer uma
gerncia manual da memria com ponteiros (mais sobre isso depois) ou se voc precisa liberar outros recursos. A sintaxe
a mesma do C# e C++:

class Demo : Object {


~Demo() {
stdout.printf("no destrutor");
}
}

Desde que o gernciamento de memria do Vala baseado na contagem de referncias invs de coleo de lixo(garbage
collection), destrutores so deterministicos e podem ser usados para implementar o padro RAII para gerenciar os
recursos (fechamento de fluxos, conexes de bancos de dados, ...).

46
Sinais

Sinais
Sinais so um sistema proveniente da classe Objeto da GLib, e so fcilmente acessveis ao Vala em todos os
descendentes dos Objetos. Um sinal reconhecvel por um programador C# como um evento, ou aos programadores
Java como uma alternativa implementar event listeners. Brevemente, um sinal um jeito simples de executar um
nmero arbitrrio de mtodos externamente identicos (ex. os com o mesmo sinal) aproximadamente no mesmo tempo. Os
mtodos atuais de execuo so internos ao gobject, e no importante aos programas Vala.

Um sinal definido como um membro de uma classe, e aparenta similar a um mtodo sem um corpo. Gerenciadores de
sinais podem ento cer adicionados ao sinal usando o mtodo connect() . Para finalizar, o exemplo a seguir tambm
introduz expresses lambda, uma forma til de escrever gerenciadores de sinais em Vala:

public class Teste : GLib.Object {

public signal void sig_1(int a);

public static int main(string[] args) {


Teste t1 = new Teste();

t1.sig_1.connect((t, a) => {
stdout.printf("%d\n", a);
});

t1.sig_1(5);

return 0;
}
}

Esse cdigo introduz uma nova classe chamada "Teste", usando uma sntaxe familiar. O primeiro mmbro dessa classe
um sinal, chamado "sig_1", que definido recebendo um inteiro. No mtodo principal do programa(main), ns primeiro
criamos uma instncia de Teste - Um requerimento desde que sinais sempre pertencem instncias da classe. Em
seguida, ns atribumos para nossa instncia um gerenciador de sinal "sig_1", no qual definimos uma expresso lambda.
A definio dita que o mtodo receber dois argumentos quais chamaremos "t" e "a", mas no provemos tipos. Nos
podemos ser concisos assim porque Vala j conhece a definio do sinal e pode compreender que tipos so requeridos.

A razo pela qual existem dois parmetros para gerir os sinais que quando um sinal emitido, o objeto ao qual ele
emitido passado como primeiro argumento ao gerenciador. O segundo argumento o que o sinal providencia.

Finalmente, ns ficamos impacientes e decidimos emitir um sinal. Ns fazemos fazemos isso chamando o sinal como se
fosse um mtodo da nossa classe, e isso permite ao gobject de tomar conta de encaminhar a mensagem a todos os
gerenciadores de sinais. Compreender os mecanismos usados para isso no um requerimento para se usar sinais em
Vala.

N.B.: Atualmente o modificador de acesso public a nica opo - todos os sinais podem ser conectados e emitidos por
qualquer parte do cdigo.

[Signal (action=true, detailed=true, run=true, no_recurse=true, no_hooks=true)]


public signal void sig_1 ();

47
Propriedades

Propriedades
uma boa prtica de orientao objetos ocultar detalhes da implementao para os suarios de suas classes(Princpio
de ocultao de informaes(em ingls)), ento voc pode depois mudar os internos sem quebrar a API pblica. Uma
pratica tornar os campos privados e prover mtodos de acessos para pegar e determinar os seus valores(getters e
setters).

Se voc um programador Java voc vai provavelmente pensar em algo assim:

class Pessoa : Object {


private int idade = 32;

public int get_idade() {


return this.idade;
}

public void set_idade(int idade) {


this.idade = idade;
}
}

Isso funciona, mas Vala pode fazer melhor. O problema que esses mtodos so incomodos de se trabalhar. Vamos
supor que voc quer incrementar a idade da pessoa em um ano:

var alice = new Pessoa();


alice.set_idade(alice.get_idade() + 1);

aqui que as propriedades entram em ao:

class Pessoa : Object {


private int _idade = 32; // prefixo sublinhado para evitar um cruzamento de nome com a propriedade

/* Propriedade */
public int idade {
get { return _idade; }
set { _idade = value; }
}
}

Essa sintaxe deve ser familiar a programadores C#. A propriedade tem um get e um set para inserir e retornar seu
valor. value uma palavra chave que representa o novo valor que deve ser atribudo a propriedade.

Agora voc pode acessar a propriedade como se ela fosse um campo pblico. Mas por trs das cenas o cdigo
executado pelos setters e getters.

var alice = new Pessoa();


alice.idade = alice.idade + 1; // ou at mais curto:
alice.idade++;

Se voc s faz a implementao padro como mostrada acima voc pode escrever as propriedades de maneira mais
curta:

class Pessoa : Object {


/* Propriedade com um getter e setter e valor padro */
public int idade { get; set; default = 32; }
}

Com propriedades voc pode mudar o trabalho interno das classes sem mudar sua API pblica. Por exemplo:

48
Propriedades

static int ano_atual = 2525;

class Pessoa : Object {


private int ano_de_nascimento = 2493;

public int idade {


get { return ano_atual - ano_de_nascimento; }
set { ano_de_nascimento = ano_atual - value; }
}
}

Agora a idade calculada na hora pelo ano de nascimento. Note que voc pode fazer mais que acessar uma simples
variavel ou atribuio com os blocos get e set. Voc poderia fazer um acesso banco de dados, logs, atualizaes de
cache, etc.

Se voc quer fazer uma propriedade somente-leitura para os usuarios da classe voc deve fazer o setter privado:

public int idade { get; private set; default = 32; }

Ou alternativamente, voc pode deixar o bloco set de fora:

class Pessoa : Object {


private int _idade = 32;

public int idade {


get { return _idade; }
}
}

Propriedades podem no apenas ter um nome mas tambm uma curta descrio(chamado nick) e uma descrio
longa(chamada blurb). Voc pode anotar esses com um atributo especial:

[Description(nick = "idade em anos", blurb = "Essa a idade da pessoa em anos")]


public int age { get; set; default = 32; }

Propriedades e suas descries adicionais podem ser requeridas em tempo de execuo. Alguns programas como a
ferramenta grfica de design de interfaces de usuario Glade faz uso dessa informao. Dessa forma Glade pode mostrar
descries legveis por humanos para propriedades dos widgets GTK+.

Toda instancia de uma classe derivada da GLib.Object tem um sinal chamado notify . Esse sinal emitido toda vez que
uma propriedade de seus objetos muda. Ento voc pode conectar a esse sinal se estiver interessado nas notificaes de
mudanas em geral:

obj.notify.connect((s, p) => {
stdout.printf("A propriedade '%s' mudou!\n", p.nome);
});

s a origem do sinal ( obj nesse exemplo), p a informao da propriedade do tipo ParamSpac para a propriedade

mudada. Se voc s est interessado nas notificaes de mudana de uma nica propriedade voc pode usar essa
sintaxe:

alice.notify["idade"].connect((s, p) => {
stdout.printf("idade mudou\n");
});

Note que nesse caso voc precisa usar a representao verbal do nome da propriedade aonde sublinhas so substituidas
por traos: nome_da_propriedade se torna nome-da-propriedade nessa representao, que a conveno de nomeao de
propriedades nos GObjects.

49
Propriedades

A notificao de mudanas pode ser desabilitada com um atributo CCode imediatamente antes da declarao da
propriedade:

public class MyObject : Object {


[CCode(notify = false)]
// sinal notify NO emitido nas mudanas da propriedade
public int sem_notificacao { get; set; }
// sinal notify emitido nas mudanas da propriedade
public int com_notificacao { get; set; }
}

H outro tipo de propriedades chamado propriedades de construo(construct properties) que so descritos depois na
seo sobre construo no estilo gobject.

Nota: no caso de sua propriedade ser do tipo struct, para receber o valor da propriedade com Object.get(), voc tem que
declarar sua varivel como no exemplo abaixo

struct Cor
{
public uint32 argb;

public Cor() { argb = 0x12345678; }


}

class Forma: GLib.Object


{
public Cor c { get; set; default = Cor(); }
}

int main()
{
Cor? c = null;
Forma f = new Forma();
f.get("c", out c);
}

Dessa forma, c uma referncia invs de uma instancia de Cor no stack. O que voc passou ao s.get() "Cor **" invs de
"Cor *".

50
Herana

Herana
Em Vala, uma classe pode derivar de uma ou zero outras classes. Na prtica provvel que este seja um, embora no
haja herana implcita como em linguagens como Java.

Quando se define uma classe que herda de outra, voc cria um relacionamento entre as classes onde as intncias da
subclasse tambm so instancias da superclasse. Isso significa que operaes em instancias da superclasse so tambm
aplicveis em instancias da subclasse. Sendo assim, quando uma instancia da superclasse requerida, uma instancia da
subclasse pode ser usada.

Quando se escreve a definio de uma classe possvel exercer controle preciso sobre quem pode acessar quais
mtodos e dados no objeto. O exemplo a seguir demostra um srie dessas opes:

class SuperClasse : GLib.Object {

private int dado;

public SuperClasse(int dado) {


this.dado = dado;
}

protected void metodo_protegido() {


}

public static void metodo_publico_estatico() {


}
}

class SubClasse : SuperClasse {

public SubClasse() {
base(10);
}
}

dado um dado membro da SuperClasse. Vai ter um membro desse tipo em qualquer instncia da SuperClasse, e
declarado privado ento s vai ser acessvel pelo cdigo que parte da SuperClasse.

metodo_protegido um mtodo instancia da SuperClasse. Voc poder executar esse mtodo apenas em uma instancia
da SuperClasse ou em uma de suas subclasses, e s no cdigo que pertence a SuperClasse ou uma de suas subclasses
- Essa ultima regra o resultado do modificador protected .

metodo_publico_estatico tem dois modificadores. O modificador static significa que esse mtodo pode ser chamado
sem posse de uma instancia da SuperClasse ou uma de suas subclasses. Como resultado, esse mtodo no ter acesso
a referencia this quando for executada. O modificador public significa que esse mtodo pode ser chamado em
qualquer cdigo, no importando o relacionamento com a SuperClasse ou suas subclasses.

Dadas estas definies, uma instncia de SubClasse vai conter todos os trs membros da SuperClasse, mas ir somente
ser capaz de acessar membros no-privados. Cdigo externo s poder acessar o mtodo pblico.

Com base um construtor da subclasse pode encadear um construtor de sua classe base.

51
Classes abstratas

Classes abstratas
Existe outro modificador para mtodos, chamado abstract . Esse modificador permite que voc descreva um mtodo que
no atualmente implementado na classe. Invs disso, ele deve ser implementado pela subclasse antes de ser chamado.
Isso permite que voc defina operaes que podem ser chamadas em todas instncias de um tipo, enquanto ensegura-se
de que todos os tipos mais especficos provem sua prpria verso da funcionalidade.

Uma classe contendo mtodos abstratos deve ser declarada abstract (abstrata) tambm. O resultado disso previnir
qualquer instanciao do tipo.

public abstract class Animal : Object {

public void comer() {


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

public abstract void diga_oi();


}

public class Tigre : Animal {

public override void diga_oi() {


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

public class Pato : Animal {

public override void diga_oi() {


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

A implementao de um mtodo abstrato deve ser marcada com override . Propriedades tambm podem ser abstratas.

52
Mtodos virtuais

Mtodos virtuais
Um mtodo virtual permite que sejam definidas implementaes padro para classes abstract (abstratas) e permitem
que uma classe filha sobreponha seu comportamento, isso diferente de esconder mtodos.

public abstract class Discador : GLib.Object {


public abstract string nome { get; protected set; }
public abstract void atualizar (string novo_nome);
public virtual bool restaurar ()
{
nome = "Sem nome";
return true;
}
}

public class ContatoCV : Discador


{
public override string nome { get; protected set; }
public override void atualizar (string novo_nome)
{
nome = "ContatoCV - " + novo_nome;
}
public override bool restaurar ()
{
nome = "ContatoCV-Nome";
stdout.printf ("CotatoCV.restaurar () implemetao!\n");
return true;
}
}

public class Contato : Discador {


public override string nome { get; protected set; }
public override void atualizar (string novo_nome)
{
name = "Contato - " + novo_nome;
}

public static void main ()


{
var c = new Contato ();
c.atualizar ("John Strauss");
stdout.printf(@"Nome: $(c.nome)\n");
c.restaurar ();
stdout.printf(@"Restaurar Nome: $(c.nome)\n");

var cv = new ContatoCV ();


cv.atualizar ("Xochitl Calva");
stdout.printf(@"Nome: $(cv.nome)\n");
cv.restaurar ();
stdout.printf(@"Restaurar Nome: $(cv.nome)\n");
stdout.printf("FIM\n");
}
}

Como voc pode ver no exemplo acima, Discador uma classe abstrata( abstract ) definindo uma propriedade abstrata
e um mtodo abstrato, mas adiciona um mtodo virtual que pode ser sobreposto pela classe derivada. A classe
Contato implementa mtodos e propriedades abstratas de Discador , enquanto usa a implementao padro de

restaurar() por no definir uma nova. A classe ContatoCV implemeta todas as definies abstratas do Discador , mas

sobrepe restaurar() para definir uma implementao prpria.

53
Interfaces

Interfaces
Uma classe em Vala pode implementar qualquer nmero de interfaces. Cada interface um tipo, como uma classe, mas
um que no pode ser instanciado. Por "implementar" uma ou mais interfaces, uma classe pode declarar suas instncias
como instncias da interface, e portanto pode ser usada em qualquer situao em que uma instncia dessa interface
esperada.

O procedimento para implementar uma interface o mesmo de herdar de classes com mtodos abstratos - se a classe
til ela deve prover implementaes para todos os mtodos que so descritos mas no ainda implementados

Uma definio simples de interface se parece assim:

public interface ITeste : GLib.Object {


public abstract int dado_1 { get; set; }
public abstract void metodo_1();
}

Esse cdigo descreve uma interface ITeste que requer GLib.Object como pai da classe implementadora e contem dois
membros. dado\_1 uma propriedade, como descrito acima, exceto que esteja declarado abstrata. Vala ir portanto no
implementar a propriedade, mas invs requerer que a classe implementando essa interface tenha uma propriedade
chamada dado_1 que tenha os dois acessores get e set - necessrio que seja abstrata( abstract ) pois as interfaces
no podem ter dados. O segundo membro metodo_1 um mtodo. Aqui declarado que esse mtodo deve ser
implementado pelas classes que implementam essa interface.

A implementao mais simples possvel dessa interface :

public class Teste1 : GLib.Object, ITeste {


public int dado_1 { get; set; }
public void metodo_1() {
}
}

E pode ser usada como a seguir:

var t = new Teste1();


t.metodo_1();

ITeste i = t;
i.metodo_1();

54
Definindo pr-requisitos

Definindo pr-requisitos
Interfaces em Vala podem no herdar de nenhuma outra interface, mas elas podem declarar outras interfaces como pr-
requisito, que funciona grosseiramente do mesmo jeito. Por exemplo, pode ser desejvel dizer que qualquer classe que
implemente uma interface List deva implementar tambm as interfaces Collection e Traversable . A sintaxe para isso
exatamente a mesma para descrever implementao de interfaces em classes:

public interface List : Collection, Traversable {


}

A definio de List no pode ser implementada em uma classe sem Collection ser implementada tambm, ento Vala
obriga o seguinte estilo de declarao para uma classe desejando implementar List, aonde todas as interfaces
implementadas tambm devem ser descritas:

public class ListClass : GLib.Object, Collection, List {


}

Interfaces Vala tambm podem ter classes como pr-requisito. Se um nome de classe dado na lista de pr-requisitos.a
interface s pode ser implementada em uma classe que deriva dessa classe. Isso usado frequentemente para garantir
que uma instncia da interface tambm uma subclasse de GLib.Object, e ento a interface pode ser usara, por exemplo,
como o tipo de uma propriedade.

O fato que interfaces no podem herdar de outras interfaces geralmente uma distino tcnica apenas - na pratica Vala
funciona da mesma forma que outras linguagens nesse ponto, mas com o recurso extra de pr-requisitos de classe.

55
Definindo padro de implementao em mtodos

Definindo padro de implementao em mtodos


Existe tambm outra diferena importante entre interfaces de Vala e Java/C# : As interfaces de Vala podem ter mtodos
no-abstratos.

Vala permite implementao de mtodos em interfaces, ento um mtodo com uma implementao padro deve ser
declarado como virtual . Devido a este fato interfaces Vala podem agir como mixins(em ingls).Isso uma forma restrita
de mltiplas heranas.

public interface Discavel : GLib.Object {


public abstract bool atentendo { get; protected set; }
public abstract void atender ();
public virtual bool suspender ()
{
atender = false;
return true;
}
}

A interface Discavel define uma propriedade abstrata chamada atendendo , aonde qualquer classe implementando essa
interface pode monitorar o estado de uma chamada, detalhes sobre atender so um problema do implementador, mas
suspender define uma implementao padro para por atendendo em falso quando uma chamada for suspensa.

public class Fone : GLib.Object, Discavel {


public bool atendendo { get; protected set; }
public void atender ()
{
/* implementao de cdigo do responder */
}

public static void main ()


{
var f = new Fone ();
if (f.suspender ())
stdout.printf("Suspeno concluda.\n");
else
stdout.printf("Erro na suspeno!\n");
stdout.printf("FIM\n");
}
}

Quando compilar e executar, voc discobrir que a classe Fone no implementa o mtodo Discavel.suspender() , mas
capaz de usa-lo, ento o resultado a mensagem Suspeno concluda .

public class SmartPhone : GLib.Object, Discavel


{
public bool atendendo { get; protected set; }
public void atender ()
{
/* implementao de cdigo do responder */
}
public bool suspender ()
{
atendendo = false;
stdout.printf ("Implementao SmartPhone.suspender ()!");
return false;
}
}

56
Definindo padro de implementao em mtodos

Nesse caso SmartPhone outra implementao ao Discavel , ento quando o mtodo suspender() chamado na
instncia de SmartPhone ele retornar falso e imprimir a mensagem Implementao SmartPhone.suspender ()! ,
escondendo completamente a implementao padro Discavel.suspender()

57
Propriedades

Propriedades
Uma interface pode definir propriedades que precisam ser implementadas para classes. A classe implementadora precisa
definir uma propriedade com a mesma assinatura e permisso de acesso ao get e set .

Como qualquer propriedade GObject, voc pode definir um corpo para o get e set da propriedade na classe
implementadora, quando nenhum corpo usado valores so set e get por padro. Se dados, voc precisa definir um
campo privado para guardar os valores da propriedade para ser usado dentro ou fora da classe.

A definio da interface Discavel , define uma propriedade atendendo . Nesse caso essa interface define um atendendo
com um protected set , permitindo uma propriedade somente leitura para qualquer objeto usando uma instncia de
Discavel , mas permite que os implementadores da classe escrevam valores nela, como a classe SmartPhone faz quando

implementa o mtodo suspender() .

58
Mixins e mtiplas heranas

Mixins e mtiplas heranas


Como descrito antes, Vala enquanto apoiado em C e GObjects, pode prover um mecanismo limitado de mtipla herana,
ai adicionar mtodos virtuais as interfaces. possvel adicionar alguns jeitos de definir implementao padro a mtodos
em classes implementadoras das interfaces e permitir que classes derivadas sobreponham esses mtodos.

Se voc definir um mtodo virtual em uma interface e implementar isso em uma classe, voc no pode sobrepor o
mtodo da interface sem deixar a classe derivada incapaz de acessar a implementao padro da interface. Considere o
caso a seguir:

public interface Callable : GLib.Object {


public abstract bool answering { get; protected set; }
public abstract void answer ();
public abstract bool hang ();
public static bool default_hang (Callable call)
{
stdout.printf ("At Callable.hang()\n");
call.answering = false;
return true;
}
}

public abstract class Caller : GLib.Object, Callable


{
public bool answering { get; protected set; }
public void answer ()
{
stdout.printf ("At Caller.answer()\n");
answering = true;
hang ();
}
public virtual bool hang () { return Callable.default_hang (this); }
}

public class TechPhone : Caller {


public string number { get; set; }
}

public class Phone : Caller {


public override bool hang () {
stdout.printf ("At Phone.hang()\n");
return false;
}

public static void main ()


{
var f = (Callable) new Phone ();
f.answer ();
if (f.hang ())
stdout.printf("Hand done.\n");
else
stdout.printf("Hand Error!\n");

var t = (Callable) new TechPhone ();


t.answer ();
if (t.hang ())
stdout.printf("Tech Hand done.\n");
else
stdout.printf("Tech Hand Error!\n");
stdout.printf("END\n");
}
}

59
Mixins e mtiplas heranas

Nesse caso, ns definimos uma interface Callable com uma implementao padro para abstract bool hang ()
chamada default_hang , ela pode ser um mtodo static ou virtual . Ento Caller a classe base implementando
Callable para as classes TechPhone e Phone , enquanto o mtodo hang () da Caller usa a implementao padro de

Callable . TechPhone no faz nada e pega Caller como classe base, usando a implementao padro do mtodo, mas

Phone sobrepe Caller.hang () e isso faz com que ele usa sua prpria implementao, permitindo sempre chama-lo

mesmo se for convertido em um objeto Callable .

Implementao explcita de mtodo

A implementao explicita de mtodos de interface permite que sejam implementadas duas interfaces que tenham os
mesmos mtodos (no propriedades) com o mesmo nome.

Exemplo:

interface Foo {
public abstract int m();
}

interface Bar {
public abstract string m();
}

class Cls: Foo, Bar {


public int Foo.m() {
return 10;
}

public string Bar.m() {


return "bar";
}
}

void main () {
var cls = new Cls ();
message ("%d %s", ((Foo) cls).m(), ((Bar) cls).m());
}

A sada ser 10 bar.

60
Polimorfismo

Polimorfismo
Polimorfismo descreve o jeito no qual um mesmo objeto pode ser usado como se fosse mais de um tipo distinto. Diversas
das tcnicas aqui descritas sugerem como isso possvel em Vala: Uma instancia de uma classe pode ser usada como
em uma instancia de uma superclasse, ou de qualquer interface implementada, sem qualquer conhecimento do seu tipo.

Uma extenso lgica desse poder permitir que um subtipo haja diferente quando endereado exatamente da mesma
forma. Isso no um conceito muito fcil de explicar, ento vamos comear com um exemplo que mostrar o que
acontece se voc no buscar esse objetivo:

class SuperClass : GLib.Object {


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

class SubClass : SuperClass {


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

Essas duas classes implementam o mesmo mtodo chamado "method_1" e a SubClass portanto contm dois mtodos
chamados "method_1", por herdar uma da SuperClass . Cada um desses podem ser chamados como o cdigo a seguir
mostra:

SubClass o1 = new SubClass();


o1.method_1();
SuperClass o2 = o1;
o2.method_1();

Isso ir resultar em dois diferentes mtodos sendo chamados. A segunda linha acredita que "o1" seja uma SubClass e vai
chamar aquela verso do mtodo. A quarta linha espera que "o2" seja uma SuperClass e vai chamar o mtodo daquela
classe.

O problema que esse exemplo expe, que qualquer cdigo mantendo uma referncia SuperClass vai chamar o
mtodo descrito naquela classe, mesmo que o objeto seja uma subclasse. O jeito de mudar esse comportamento
usando mtodos virtuais. Considere a seguinte verso reescrita do ltimo exemplo:

class SuperClass : GLib.Object {


public virtual void method_1() {
stdout.printf("SuperClass.method_1()\n");
}
}

class SubClass : SuperClass {


public override void method_1() {
stdout.printf("SubClass.method_1()\n");
}
}

Quando esse cdigo usado da mesma forma que antes, O mtodo "method_1" da SubClass ser chamado duas vezes.
Isso porque nos dissemos ao sistema que "method_1" um mtodo virtual, significando que se for sobreposto em uma
subclasse, essa nova verso sempre ser executada nas instncias dessa subclasse, independente do conhecimento do
instanciador.

Essa distino provavelmente familiar programadores de algumas linguagens, como C++, mas de fato o oposto do
estilo de linguagens como Java, no qual os passos devem ser tomados para prevenir que um mtodo seja virtual.

61
Polimorfismo

Voc provavelmente reconheceu tambm agora que quando um mtodo declarado como abstract ele tambm deve
ser virtual. Caso contrrio, no seria possvel executar dado mtodo numa instncia do tipo em que foi declarado. Quando
implementamos um mtodo abstrato numa subclasse, voc pode portanto escolher declarar a implementao como
override , assim passando a natureza do mtodo virtual, e permitindo que subtipos faam o mesmo se for desejado.

Tambm possvel implementar mtodos de interface de forma que as subclasses possam mudar a implementao. O
processo nesse caso declarar a implemetao inicial como mtodo virtual , e ento as subclasses podem sobrepor
quando necessrio.

Na hora de escrever uma classe, comum querer usar funcionalidades definida em uma classe que voc herdou. Isso
complicado quando o mesmo nome de mtodo usado mais de uma vez na arvore de heranas da sua classe. Para esse
propsito Vala prov a palavra chave base . O caso mais comum quando voc sobreps um mtodo virtual pra prover
funcionalidades extras, mas ainda quer que o mtodo da classe base seja chamado. O exemplo a seguir mostra esse
caso:

public override void method_name() {


base.method_name();
extra_task();
}

Vala tambm permite que as propriedades sejam virtuais:

class SuperClass : GLib.Object {


public virtual string prop_1 {
get {
return "SuperClass.prop_1";
}
}
}

class SubClass : SuperClass {


public override string prop_1 {
get {
return "SubClass.prop_1";
}
}

62
Ocultao de Mtodos

Ocultao de Mtodos
Ao usar o modificador new voc pode ocultar um mtodo herdado com um novo mtodo de mesmo nome. O novo
mtodo pode ter uma assinatura diferente. A ocultao de mtodos no deve ser confundida com a sobreposio de
mtodos(method overriding), porque a ocultao de mtodos no exibe comportamentos polimrficos.

class Foo : Object {


public void my_method() { }
}

class Bar : Foo {


public new void my_method() { }
}

Voc ainda pode chamar o mtodo original convertendo para a classe base ou interface:

void main() {
var bar = new Bar();
bar.my_method();
(bar as Foo).my_method();
}

63
Informao do tipo em tempo de execuo

Informao do tipo em tempo de execuo


Desde que as classes Vala so registradas em tempo de execuo e cada instncia carrega informao do seu tipo voc
pode checar dinamicamente o tipo de um objeto com o operador is :

bool b = object is SomeTypeName;

Voc pode receber a informao de tipo de instncias Object com o mtodo get_type () :

Type type = object.get_type();


stdout.printf("%s\n", type.name());

Com o operador typeof () voc pode receber a informao de um tipo diretamente. Dessa informao de tipo voc pode
criar novas instncias com Object.new () :

Type type = typeof(Foo);


Foo foo = (Foo) Object.new(type);

Qual construtor ser chamado? o bloco constuct {} que ser descrito na seo sobre construes do estilo gobject.

64
Converso dinmica de tipo

Converso dinmica de tipo


Para a converso dinmica, a varivel moldada por uma expresso psfixa as NomeDoTipoDesejado . Vala ir incluir uma
checagem de tipo na execuo pra assegurar que a converso razovel - se for uma converso ilegal, ser retornado
null . Entretanto, isso requer tanto que o tipo original quanto o alvo sejam classes do tipo referncia.

Por exemplo,

Button b = widget as Button;

Se por alguma razo a classe da instncia widget no a classe Button ou alguma de suas subclasses ou no
implementa a interface Button, b ser null . Essa converso equivalente :

Button b = (widget is Button) ? (Button) widget : null;

65
Genricos

Genricos
Vala incli um sistema genrico de tempo de execuo, pelo qual uma particular instncia de uma classe pode ser restrita
com um tipo particular ou um conjunto de tipos escolhidos no tempo de construo. Essa restrio geralmente usada
para exigir que o dado guardado no objeto deve ser de um tipo particular, por exemplo a fim de implementar uma lista de
objetos de um certo tipo. No exemplo, Vala poderia ter certeza que somente o objeto de um tipo requerido pudesse ser
adicionado a lista, e que na reaquisio todos os objetos poderiam ser convertidos naquele tipo.

Em Vala, genricos so manipulados enquanto o programa est em execuo. Quando voc define uma classe que pode
ser restrito um tipo, existe apenas uma nica classe, com cada instncia personalizada individualmente. Isso contrasta
com C++ que cria uma nova classe para cada tipo de restrio requerido - um sistema similar a Vala usado em Java.
Isso tem vrias consequencias, as mais importantes: os membros estticos so compartilhados por um tipo como um todo,
independente das restries contidas em cada instncia, e dadas classe e subclasse, um genrico aprimorado por uma
subclasse pode ser usado como um genrico aprimorado pela classe.

O cdigo a seguir demonstra como utilizar o sistema genrico pra definir uma classe envoltria mnima(wrapper):

public class Wrapper<G> : GLib.Object {


private G data;

public void set_data(G data) {


this.data = data;
}

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

Essa classe "Wrapper" deve ser restrita com um tipo para ser instanciada - nesse caso o tipo ser identificado como "G", e
suas instncias de classe guardaro um objeto do tipo "G", e tero mtodos para receber ou enviar tal objeto. (A razo
para esse exemplo para explicar que atualmente uma classe genrica no pode usar propriedades de seu tipo restrito,
portanto invs disso essa classe tem mtodos get e set).

A fim de instnciar essa classe, um tipo deve ser escolhido, por exemplo o tipo embutido string (em Vala no existem
restries sobre quais tipos podem ser usados como genricos).

var wrapper = new Wrapper<string>();


wrapper.set_data("test");
var data = wrapper.get_data();

Como voc pode ver, quando o dado retornado do envoltrio, atribuido a um identificador sem tipo explicito. Isso
possvel porque Vala conhece o tipo de objeto que est em cada instncia do envoltrio, sendo assim ele pode fazer isso.

O fato que Vala no cria multiplas classes para voc pelas suas definies genricas significa que voc pode fazer o
cdigo a seguir:

class TestClass : GLib.Object {


}

void accept_object_wrapper(Wrapper<Glib.Object> w) {
}

...
var test_wrapper = new Wrapper<TestClass>();
accept_object_wrapper(test_wrapper);
...

66
Genricos

Desde que todas as instncias TestClass tambm so Object , o mtodo "accept_object_wrapper" ir aceitar qualquer
objeto que for passado, e tratar seus objetos envolvidos como instncias de GLib.Object .

67
Construo estilo GObject

Construo estilo GObject


Vala suporta um esquema alternativo de construo que levemente diferente dos descritos anteriormente. Esse
esquema mais parecido com o jeito que os GObject so construidos. Qual voc vai preferir vai depender se voc veio
dos lado dos GObjects ou do Java e/ou C#. O esquema de construo dos GObject introduzem novos elementos
sintticos:

propriedades de construo, uma chamada especial Object(...) e um bloco construct . Vamos dar uma olhada no
funcionamento:

public class Person : Object {

/* Construction properties */
public string name { get; construct; }
public int age { get; construct set; }

public Person(string name) {


Object(name: name);
}

public Person.with_age(string name, int years) {


Object(name: name, age: years);
}

construct {
// do anything else
stdout.printf("Welcome %s\n", this.name);
}
}

Com o esquema de construo do estilo GObject cada mtodo de construo s pode conter uma chamada Object (...)
para determinar os to falados propriedades de construo(construct properties). A chamada Object (...) recebe um
varivel nmero de argumentos nomeados na forma de propriedade: valor . Essas propriedades precisam ser declaradas
como construct ou set . Elas sero atribudas com os dados valores e depois todos blocos construct {} na hierarquia
do GLib.Object abaixo da nossa classe ser chamado.

O bloco construct garantido de ser chamadoquando uma instncia da classe criada, mesmo se ela for criada como
um subtipo. No tem parmetros ou retorno de valores. Dentro desse bloco voc pode chamar outros mtodos e atribuir
variveis membros que forem necessrias.

Propriedades de construo so definidas como propriedades get e set , e portanto podem executar cdigos arbitrrios
na atribuio. Se voc precisa fazer inicializaes baseado numa nica propriedade de construo, possvel escrever
um bloco construct personalizado para a propriedade, que ser executado imediatamente na atribuio, e antes de
outros cdigos de construo.

Se uma propriedade de construo declarada sem set ela ser uma to falada propriedade somente construo, que
significa que s pode ser atribuida na construo. No exemplo abaixo name uma propriedade somente construo.

Aqui temos um sumrio de vrios tipos de propriedades juntas com nomenclaturas usualmente encontradas na
documentao de bibliotecas baseadas em GObject.

public int a { get; private set; } // Read


public int b { private get; set; } // Write
public int c { get; set; } // Read / Write
public int d { get; set construct; } // Read / Write / Construct
public int e { get; construct; } // Read / Write-Construct-Only

68
Construo estilo GObject

Em alguns casos voc tambm vai querer executar algumas aes - no quando instncias das classes so criadas - mas
quando a classe propriamente dita criada na execuo dos GObject. Na terminologia dos GObject ns estamos falando
sobre os trechos de cdigo que rodam dentro da funo class_init para a classe em questo. Em Java isso conhecido
como static initializer blocks(Blocos de inicializao esttica). Em Vala isso se parece assim:

/* This snippet of code is run when the class


* is registered with the type system */
static construct {
...
}

69
Recursos experimentais

Recursos esperimentais
Algumas caractersticas de Vala so experimentais. Isso significa que elas no esto totalmente testadas e podem estar
sujeitas a alteraes em verses futuras.

70
Relao encadeada

Relao encadeada
Este recurso permite que voc escreva expresses relacionais complexas como

if (1 < a && a < 5) {}

if (0 < a && a < b && b < c && c < d && d < 255) {
// do something
}

De uma forma mais natural:

if (1 < a < 5) {}

if (0 < a < b < c < d < 255) {


// do something
}

71
Expresso regular literal

Expresso regular literal


Expresses regulares so uma tcnica poderosa para a correspondncia de padres em strings. Vala tem suporte
experimental para expresses regulares literais ( /regex/ ). Exemplo:

string email = "tux@kernel.org";


if (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.match(email)) {
stdout.printf("Valid email address\n");
}

O i direita faz com que a expresso no seja insensvel. Voc pode armazenar uma expresso regular em uma varivel
do tipo Regex:

Regex regex = /foo/;

Um exemplo de substituio de string usando expresso regular:

var r = /(foo|bar|cow)/;
var o = r.replace ("this foo is great", -1, 0, "thing");
print ("%s\n", o);

Os seguintes caracteres direita podem ser usados:

i, por padro as letras combinam letras maisculas e minsculas

m, as construes no "incio de linha" e no "fim de linha" coincidem imediatamente aps ou imediatamente antes de
qualquer nova linha na seqncia, respectivamente, bem como no incio e no final.

s, um metacaracter . No padro corresponde a todos os caracteres, incluindo nova linhas. Sem ele, as novas linhas
so excludas.

x, os caracteres de espao em branco no padro so totalmente ignorados, exceto quando escapados ou dentro de
uma classe de caracteres.

72
Modo no-nulo rigoroso

Modo no-nulo rigoroso


Se voc compilar seu cdigo com --enable-experimental-non-null o compilador Vala ser executado verificando se o tipo
no-nulo e considerar que o tipo every no deve ser nulo por padro, a menos que seja explicitamente declarado nulo
por marcao com um ponto de interrogao:

Object o1 = new Object(); // not nullable


Object? o2 = new Object(); // nullable

O compilador ir executar uma anlise de tempo de compilao esttica para garantir que nenhuma referncia nula seja
atribuda a uma referncia no-nula. Por exemplo, Isso no ser possvel:

o1 = o2;

o2 pode ser null e o1 foi declarado no-nulo, portanto, esta atribuio proibida. No entanto, voc pode substituir esse
comportamento com um elenco explcito no-nulo se tiver certeza de que o2 no nulo:

o1 = (!) o2;

Este modo rigoroso de no-nulo ajuda a evitar indesejaveis erros de derreferenciao em null(objetos nulos). Esse recurso
poderia chegar ao seu pleno potncial se a nulabilidade dos tipos de retorno nos bindings(vinculos de bibliotecas C)
fossem marcados corretamente, o que no sempre o caso.

73
Bibliotecas

Bibliotecas
A nvel do sistema, uma biblioteca Vala exatamente uma biblioteca C e, portanto, as mesmas ferramentas so usadas. A
fim de tornar o processo mais simples, e para que o compilador Vala possa entender o processo, h um nvel extra de
informaes especficas de Vala.

Uma "biblioteca Vala" , portanto, a parte do sistema:

Uma biblioteca de sistema (por exemplo, libgee.so)


Uma entrada pkg-config (por exemplo, gee-0.8.pc)

Ambos esto instalados nos locais padro. E os arquivos especficos de Vala:

Um arquivo VAPI (por exemplo, gee-0.8.vapi)


Um arquivo de dependncia opcional (por exemplo, gee-0.8.deps)

Esses arquivos sero explicados mais adiante nesta seo. Deve-se notar que os nomes das bibliotecas so os mesmos
nos arquivos especficos de Vala como nos arquivos pkg-config.

74
Usando bibliotecas

Usando bibliotecas
Usar uma biblioteca em Vala amplamente automatizado se voc usar o compilador valac. Os arquivos de biblioteca
especficos Vala compem o que conhecido como um pacote. Voc diz ao compilador que um pacote necessrio pelo
seu programa da seguinte maneira:

$ valac --pkg gee-1.0 test.vala

Este comando significa que seu programa pode usar qualquer uma das definies no arquivo gee-1.0.vapi, e tambm
qualquer em qualquer um dos pacotes que gee-1.0 depende. Essas dependncias seriam listadas em gee-1.0.deps se
houvesse alguma. Neste exemplo valac definido para construir todo o caminho para o binrio e, portanto, incorporar
informaes do pkg-config para ligar as bibliotecas corretas. por isso que os nomes do pkg-config tambm so usados
para nomes de pacotes Vala.

Os pacotes so geralmente usados com namespaces, mas no so tecnicamente relacionados. Isso significa que, mesmo
que seu aplicativo seja construdo com referncia ao pacote, voc ainda deve incluir as instrues using necessrias em
cada arquivo, conforme apropriado, ou usar os nomes totalmente qualificados de todos os smbolos.

Tambm possvel tratar uma biblioteca local (que no est instalada) como um pacote. Para comparao, a prpria Vala
usa uma verso interna de Gee. Quando o valac construdo ele cria um arquivo VAPI desta biblioteca interna e usa-o
aproximadamente da seguinte maneira:

$ valac --vapidir ../gee --pkg gee ...

Para obter detalhes sobre como gerar esta biblioteca, consulte a prxima seo ou o exemplo.

75
Criando uma biblioteca

Criando uma biblioteca


Usando Autotools
possvel usar Autotools para criar uma biblioteca escrita em Vala. Uma biblioteca criada usando o cdigo C gerado
pelo compilador Vala, vinculando e instalando como qualquer outra biblioteca. Ento voc precisa dizer quais arquivos C
devem ser usados para criar a biblioteca e quais deles devem ser distribuveis, permitindo que outros compilem um
arquivo do tipo tar sem Vala, usando apenas comandos Autotools padro: configure, make and make install.

Compilao e comando de vinculao using


A Vala ainda no capaz de criar bibliotecas dinmicas ou estticas diretamente. Para criar uma biblioteca, prossiga com
a opo -c (compilar somente) e vincule os arquivos de objeto com seu vinculador favorito, ou seja, libtool ou ar .

$ valac -c ...(source files)


$ ar cx ...(object files)

Ou compilando o cdigo C intermedirio com gcc

$ valac -C ...(source files)


$ gcc -o my-best-library.so --shared -fPIC ...(compiled C code files)...

76
Construindo bibliotecas com VAPI

Construindo bibliotecas com VAPI


Os arquivos VAPI so descries da interface pblica de bibliotecas externas de Vala. Quando uma biblioteca escrita em
Vala, este arquivo criado pelo compilador Vala e, basicamente, um ajuntamento de todas as definies pblicas de todos
os arquivos de origem Vala. Para uma biblioteca escrita em C, o arquivo VAPI fica mais complicado, especialmente se as
convenes de nomenclatura da biblioteca no seguem a conveno GLib. O arquivo VAPI neste caso conter muitas
anotaes descrevendo como a interface Vala padronizada ficar na verso C.

O processo de criar geralmente equivale a trs etapas,

Executar vala-gen-introspect para extrair metadados da biblioteca C.


Adicionar metadados extras para padronizar a interface ou fazer vrias outras alteraes.
Gerar um arquivo VAPI das fontes acima usando vapigen.

Instrues especficas sobre como gerar bindings esto no Vala Bindings Tutorial

77
Ferramentas

Ferramentas
Vala possui vrios programas para ajud-lo a construir e trabalhar com aplicativos Vala. Para obter mais detalhes de cada
ferramenta, consulte o site.

valac
valac o compilador Vala. Sua funo principal transformar o cdigo Vala em cdigo C compilvel, embora tambm
possa automatizar todo o projeto de construo e link em casos simples.

Um exemplo simples:

$ valac -o appname --pkg gee-1.0 file_name_1.vala file_name_2.vala

O parmetro -o solicita que um arquivo de objeto seja criado, em vez de apenas produzir arquivos de origem C. A opo
--pkg diz que essa compilao precisa de informaes do pacote gee-1.0. No necessrio especificar detalhes sobre

quais bibliotecas ser necessrio vincular, o pacote tem essas informaes internamente. Finalmente, fornecida uma
lista de arquivos de origem. Se voc precisar de um processo de compilao mais complicado, use a opo -C para
gerar arquivos C em vez de um binrio e continuar o processo manualmente ou atravs de um script.

vapigen
vapigen uma ferramenta para fazer Bindings. Ele cria arquivos VAPI a partir de metadados de uma biblioteca e qualquer
informao extra necessria. Veja tambm Vala Bindings Tutorial.

78

Das könnte Ihnen auch gefallen