Академический Документы
Профессиональный Документы
Культура Документы
índice
3 notícias/links
Regresso ao Trabalho
4 snippets
tema de capa Voltamos a Setembro, mês do inevitável regresso às aulas para os estudantes
7 - Construção de Diagrama portugueses, após as prolongadas e muito apreciadas férias de Verão.
de Blocos
Subitamente, milhares de jovens vêem-se envolvidos numa corrida à
a programar preparação para as aulas, para muitos o famoso primeiro contacto com o
19 - Acesso de BDs remotas Ensino Superior, as candidaturas, matrículas, e por vezes a adaptação a uma
24
em Windows Mobile 6 nova cidade. Todo este repentino movimento após as férias custa e não é
- Lua – Linguagem de
Programação – Parte I propriamente agradável pensar no ano de trabalho que se avizinha, mas para
31 - Templates T4 projectos como o nosso, que vivem principalmente da vontade e
disponibilidade de estudantes voluntários, este é o regresso à normalidade.
equipa PROGRAMAR É natural que o Verão seja a época baixa no que diz respeito a qualquer tipo de
actividade extra-profissional. No caso particular da revista, grande parte da
coordenadores
Joel Ramos
equipa, incluindo redactores, revisores, colaboradores e mesmo
Pedro Abreu coordenadores, esteve pouco disponível durante a preparação desta edição, o
que nos obrigou a adiar o lançamento um mês, tal como no Verão passado -
editor adiamento que lamentamos e quanto ao qual esperamos compreensão dos
António Silva leitores. Contrariando a pouca participação, destacamos e agradecemos ao
nosso editor António Silva, pela forma como conseguiu, de forma autónoma e
capa praticamente individual, transformar um conjunto de artigos em mais uma
Maurício Rodrigues edição que esperamos estar à altura das anteriores.
redacção Se, por um lado, podemos agradecer os esforços dos que construíram esta
Augusto Manzano edição e têm permitido manter este projecto mais ou menos regular, por outro
Bruno Oliveira as dificuldades que enfrentamos nestes períodos de férias exigem reflexão.
Jorge Paulino Não há forma de garantir que uma edição terá participação suficiente, e são
Miguel Alho momentos como este que nos mostram quão abalável é um projecto desta
dimensão que julgamos sólido, pelo simples facto de sermos uma equipa de
equipa de revisão voluntários e de não haver quaisquer obrigações por parte dos colaboradores.
Bruno Oliveira Provavelmente este é um problema comum a todos os projectos deste tipo que
Fernando Martins
exigem actividade regular, mas é importante minimizá-lo e encontrar
Miguel Rentes
Nuno João
alternativas que nos permitam evitar o fracasso.
Pedro Abreu
<2>
notícias/links
<3>
snippets - vb.net
Movimentação de Controlos
em Run-Time
Quando é necessário movimentar controlos com o rato, existem diferentes códigos que necessitam de cálculos, variáveis, etc,
de modo a arrastar o controlo de um lugar para o outro, enquanto o botão do rato estiver pressionado.
Se é verdade que não é muito utilizado é verdade que quando é preciso não é um processo muito simples de fazer (pelo
menos dá algum trabalho).
A forma mais simples de o fazer (que eu tenha conhecimento) é utilizando o método DefWndProc() que permite enviar
mensagens para o sistema. É uma utilização de subclasses que irá fazer o mesmo que o Windows faz quando o utilizador
pressiona o rato na barra de título e arrasta-o.
Ora isto permite simplificar uma série de coisas como arrastar um controlo (como por exemplo uma Label ou TextBox) ou
mesmo o próprio Form. No caso do Form, e quando este não tem barra de titulo, dá imenso jeito.
End If
End Sub
É possível ainda utilizar outras constantes para fazer outras acções, como por exemplo utilizando a HTBOTTOMRIGHT (Const
HTBOTTOMRIGHT As Integer = 17) em vez da HTCAPTION, que irá efectuar o resize do Form. A constante
HTBOTTOMRIGHT é a indicação de que o utilizador está a fazer o redimencionamento do Form no canto inferior direito.
<4>
snippets - vb.net
Existem duas alternativas para a gestão de imagens: guardar apenas a localização e colocar a imagem no servidor ou gravar a
imagem directamente num campo.
Para inserir a imagem é necessário ler, gravar num array de bytes e finalmente utilizar esse array para gravar na base de
dados.
Try
' Cria um novo FileStream para leitura da imagem
Dim fs As New IO.FileStream("c:\image.jpg", IO.FileMode.Open,
IO.FileAccess.Read)
connection.Open()
Catch ex As Exception
MessageBox.Show(ex.Message, My.Application.Info.Title, MessageBoxButtons.OK,
MessageBoxIcon.Error)
End Try
<5>
Estás a ver o que não fizeste?
Esta página está em branco por tua culpa!
http://www.revista-programar.info/front/yourpage
<6>
tema de capa
<7>
tema de capa
<8>
tema de capa
<9>
tema de capa
<10>
tema de capa
<11>
tema de capa
Torna-se fundamental em operações de tomada de decisão A figura 7 apresenta o formato do ciclo de repetição
simples ou composta identificar qual o lado do diagrama incondicional do tipo for. Este tipo de ciclo executa as
que representa a acção verdadeira e a acção falsa. Isto é operações a ele subordinadas por uma variável de controlo
necessário, uma vez que não existe um lado predefinido iniciada por um valor, finalizado por outro valor diferente do
para a acção verdadeira ou falsa. valor inicial, podendo ser maior ou menor. A operação de
incremento ou decremento é efectuada por um contador em
A figura 5 apresenta o formato do ciclo de repetição cada passo de execução. Supondo um contador crescente de
condicional do tipo while...do. Este tipo de ciclo executa as 1 a 10 com passo 1 positivo, sugere-se escrever na parte
operações a ele subordinadas enquanto a condição for interna do símbolo preparação a descrição I ÿ 1, 10, 1; no
verdadeira. Após a condição se tornar falsa, o ciclo é qual I é a variável contador e as demais informações são
encerrado e o fluxo de acção do programa continua sua respectivamente a inicialização da contagem, a finalização
execução fora do ciclo de repetição. da contagem e o incremento entre o início e o fim da
contagem. Se for utilizado um contador decrescente de 10 a
1 com passo 1 negativo sugere-se utilizar a descrição I ÿ 10,
1, -1.
A figura 6 apresenta o formato do ciclo de repetição Figura 7 – Representação de ciclo incondicional do tipo para.
condicional do tipo do...while. Esse tipo de ciclo executa as
operações a ele subordinadas até que a condição seja
verdadeira. Após a condição se tornar verdadeira, o ciclo é As figuras 5, 6 e 7 sugerem uma forma de representação de
encerrado e o fluxo de acção do programa continua sua ciclos de repetição mais intimamente focada no contexto
execução fora do ciclo de repetição. lógico da execução do código de programa num
computador. No entanto, na norma ISO 5807-1985 (E), é
sugerido o uso da estrutura gráfica representada pela figura
8.
<12>
tema de capa
<13>
tema de capa
<14>
tema de capa
A figura 17 apresenta um exemplo de conexão da linha de sentido, é necessário definir um procedimento padrão para
raciocínio lógico entre páginas, sugerido na norma ISO o uso desses elementos de forma mais organizada e
5807-1985 (E), que dispensa qualquer comentário, pois padronizada, conforme se apresenta a seguir.
apresenta-se de forma clara e objectiva. De notar que a
indicação “A” dentro dos conectores é apenas uma Operadores aritméticos
referência ao ponto de conexão, podendo ser utilizada para
esta representação outras letras e mesmo números. Outro Os operadores aritméticos são responsáveis pela
detalhe com o uso de conectores é a possibilidade de representação das operações matemáticas a serem
representarem conexões na mesma página. Nesse caso, realizadas numa acção de processamento de cálculo. A
utiliza-se apenas os conectores, suprimindo a linha tracejada tabela seguinte sugere uma forma padrão para a
e a nota de descrição do ponto de conexão. representação de cada operador aritmético a ser utilizado.
• operadores relacionais;
• operadores lógicos.
<15>
tema de capa
Note que, na forma de expressão aritmética, o conceito de x’ O uso de um operador relacional será sempre definido no
(x linha) está representado pela definição da variável X1 e o símbolo de decisão num diagrama de blocos, obedecendo à
conceito de x” (x duas linhas) está representado pela estrutura sugerida na figura 19.
definição da variável X2.
Operadores lógicos
Operadores relacionais
Simbolo Significado
= igual a
<> diferente de
> maior que
< menor que Figura 20 – Exemplos de uso de operadores lógicos.
>= maior ou igual que
<= menor ou igual que
<16>
tema de capa
Bibliografia
BERG, A. C. & FIGUEIRÓ, J. P., Lógica de Programação,
Canoas, 1998, ULBRA, 168p.
PRESSMAN, R. S., Engenharia de Software, São Paulo,
1995, Makron Books, 1056p.
GOLDSTEIN, H. H. & VON NEUMANN, J. Planning and
Coding Problems of an Electronic Computing Instrument.
Figura 22 – Definição de valor lógico em uma condição New York, In A. H. Taub (Eds.), von Neumann, J., 1947,
Collected Works, McMillan. pp. 80-151.
augusto.manzano@portugal-a-programar.org
Augusto Manzano
<17>
<18>
a programar
Pré-requisitos
Antes de colocarmos mãos à obra, necessitamos de
ferramentas para trabalhar. Começamos então, por efectuar
o download do Microsoft SQL Server 2005 Express Edition
no site da Microsoft (também pode ser a versão profissional)
(http://www.microsoft.com/downloads/details.aspx?FamilyID
=220549b5-0b07-4448-8848-dcc397514b41&displaylang=pt- Vá a INICIAR -> PROGRAMAS -> MICROSOFT SQL SERVER
br). Na instalação da aplicação, quando surgir a seguinte 2005 -> CONFIGURATION TOOLS -> SQL SERVER
janela, seleccione Modo Misto (autenticação do Windows e SURFACE AREA CONFIGURATION. De seguida, seleccione:
autenticação do sql server), e introduza uma password à sua Surface Área Configuration for Services and Connections.
escolha. A partir deste ponto, apenas necessita de seguir as
instruções do instalador.
<19>
a programar
Nesta nova janela seleccione (à esquerda) Remote Por fim, reinicie o computador para que as alterações
Connections e à direita a opção Local and remote surtam efeito (ou reinicie novamente os serviços). Já
connections -> using TCP/IP only. De seguida, clique em possuímos o SQL SERVER configurado e a base de dados
SQL Server Browser e certifique-se que a opção Startup com informação suficiente para que possamos testar a
type está em Automatic. Pressione Apply e seleccione Start, ligação. Chegou então o momento de configurar o Visual
no botão correspondente. De seguida, seleccione o item Studio e começar a programar.
Service do Database Engine e seleccione o botão stop Nota importante: Se estiver a utilizar Windows Vista
seguidamente de start para reiniciar os serviços. poderão surgir problemas de permissões, como por
exemplo, não lhe ser permitido parar os serviços do SQL
Neste exemplo, vamos utilizar a porta 1433 na ligação Server. Se tal acontecer, pode tentar reiniciar o computador
remota. Para configurar a porta dirija-se a INICIAR -> ou então entrar como administrador, efectuar as
PROGRAMAS -> MICROSOFT SQL SERVER 2005 -> configurações e voltar a entrar como um utilizador normal.
CONFIGURATION TOOLS -> SQL SERVER
CONFIGURATION MANAGER.
Configuração Visual Studio
• ActiveSync 4.5
http://www.microsoft.com/downloads/details.aspx?FamilyID
=9E641C34-6F7F-404D-A04B-
DC09F8141141&displaylang=pt-br
<20>
a programar
TestaLigacao("192.168.1.2","1433","test
e","sa","1234");
}
<21>
a programar
O primeiro parâmetro é o seu ip da rede, o segundo a porta Altere o seu método TestaLigação (ou crie outro) de modo a
de ligação que definiu, “teste” o nome da base de dados que o método apenas abra a ligação e a atribua à variável
criada, “sa” o utilizador e 1234 é a password que coloquei comm global da classe. Neste exemplo, optei por criar um
quando instalei o SQL Server 2005 (não muito original diga- método novo chamado Abre_ligacao.
se).
Nota: Se não sabe qual o seu IP, vá ao menu iniciar ->
executar e digite cmd. Quando surgir a janela do DOS digite private void Abre_ligacao(String ip,
o comando IPCONFIG e será exibida a informação sobre o String porta,String nomeBd, String
seu IP. username, String password)
Grave o projecto e execute através do botão start. Quando {
surgir a janela de escolha do emulador, pode escolher Connection = "Data Source=" +
aquele que desejar, neste exemplo optei por Windows ip + "," + porta + ";Initial Catalog="
Mobile 6 Classic emulator. + nomeBd + ";User ID=" + username +
Quando o emulador iniciar, seja paciente e aguarde que o ";Password=" + password + ";";
emulador compile o programa. Quando o emulador é comm = new
iniciado pela primeira vez, demora algum tempo a ficar SqlConnection(Connection);
preparado. Após surgir o seu formulário no emulador, try
certifique-se que o emulador tem acesso à internet, ou se {
tem IP da sua rede. comm.Open();
Para isso, na janela do emulador selecione File-> configure }
catch
{
MessageBox. Show("Erro na
ligação");
}
SELECT:
<22>
a programar
bruno.oliveira@portugal-a-programar.org
Bruno Oliveira
<23>
a programar
<24>
a programar
Caso tenha obtido a cópia para o sistema operativo MacOS Os dados de uma linguagem de programação são
X Leopard ou Linux de 32 bits (ou de 64 bits) crie a partir da representados por elementos a serem processadas por um
pasta do utilizador a pasta “lua5”, descompacte os computador electrónico. A linguagem de programação Lua
conteúdos dos dois arquivos na pasta “lua5” e para fazer uso fornece ao programador um conjunto de tipos de dados
do interpretador Lua vá até a pasta “lua5” por meio da predefinidos e dinâmicos que são: nil (para a definição de
janela Terminal digite no prompt a instrução: um valor indefinido), number (para a definição de valores
numéricos em notação científica, real ou inteiro), string
(para a definição de valores alfanuméricos delimitados entre
./lua5.1 nome_do_programa[.extensão]
./lua5.1 nome_do_programa[.extensão] aspas ou entre apóstrofos e o uso de delimitadores de
escape), function (para a definição de valor do tipo função),
userdata (para a definição de valores do tipo apontador
Variáveis e Constantes quando se associa a linguagem LUA com a linguagem C) e
table (para a definição de tabelas de valores).
Para usar um determinado dado é necessário que este dado O tipo number é usado no sentido de representar valores
esteja associado a uma variável, sendo esta variável a região numéricos, independentemente dos valores numéricos
de memória principal de um computador, previamente serem do tipo inteiro ou real. Por exemplo, o valor 5 pode
identificada por um rótulo, que tem por finalidade ser representado em lua como:
armazenar um determinado valor (dado) por um
determinado espaço de tempo. Uma variável armazena A A= 5= 5
apenas um valor de cada vez. É considerado valor um A A= 5.0
= 5.0
conteúdo numérico, alfabético, alfanumérico ou lógico. A A= 0.5e1
= 0.5e1
O nome (também denominado rótulo) de uma variável é A A= 50e-1
= 50e-1
utilizado para sua identificação e posterior uso dentro de um
programa, portanto é necessário estabelecer algumas
regras para a definição do nome de uma variável: O tipo string é usado no sentido de representar uma cadeia
de caracteres delimitada por aspas ou por apóstrofos que
• Nomes de variável podem ter um ou mais caracteres; esteja definida em apenas uma linha de código ou então por
• O primeiro carácter do nome de uma variável não meio de parênteses rectos duplos onde a sequência de
pode ser, em hipótese alguma, um número; deve ser sempre caracteres poderá estar escrita em mais de uma linha de
um carácter alfabético; código. Dentro da fronteira de uma sequência de caracteres
• O nome de uma variável não pode conter espaços pode-se fazer uso das sequências de especiais:
em branco;
• Não pode ser um nome de uma variável uma palavra \n new line (nova linha)
reservada a uma instrução ou identificador da linguagem \t tab (tabulação horizontal)
Lua; \r carriage return (retorno de carro – <Enter>)
• Não podem ser utilizados outros caracteres no nome \v vertical tab (tabulação vertical)
de uma variável, a não ser que sejam letras e números, com \f form feed
excepção do carácter underline "_", que pode ser usado para \xxx carácter com código decimal xxx
simular a separação de palavras compostas, como: \a bell (campainha)
NOME_ALUNO. \b backspace (retorno de espaço)
\" aspas (")
Deve-se ainda considerar que dentro de um programa uma \' apóstrofo (')
variável pode exercer dois papéis. O papel de acção, quando \\ barra invertida (\)
é modificada ao longo do programa para apresentar um
<25>
a programar
A aplicação dos caracteres especiais dentro de uma armazenamento dentro de uma variável Lua de um
sequência de caracteres (string) possibilita o uso de alguns apontador definido num código de programa escrito em C.
efeitos dentro da sequência de caracteres em uso. Por Assim sendo, userdata corresponde ao tipo void* da
exemplo: linguagem de programação C, podendo ser utilizado apenas
para comparação de igualdade ou atribuição entre valores
do mesmo tipo tanto utilizados em C como utilizadores em
TEXTO1
TEXTO1= "Utilize a tecla '<Enter>'"
= "Utilize a tecla '<Enter>'" Lua. O tipo userdata é útil em situações que há a
TEXTO2 = 'Utilize a tecla \'<Enter>\''
TEXTO2 = 'Utilize a tecla \'<Enter>\'' necessidade de se fazer a ligação de código de programa
entre a linguagem de programação Lua e a linguagem de
programação C (Lua-C). No entanto, este tipo de dados não
Observe que a variável TEXTO1 está a ser atribuída com o podem ser utilizados em programas escritos apenas com
valor da sequência de caracteres "Utilize a tecla '<Enter>'". código de linguagem de programação Lua.
Note que o uso de aspas simples dentro da sequência de O tipo table é usado para a definição de variáveis compostas
caracteres ocorre de forma simples por estarem os símbolos que permitem o uso de elementos indexados em matrizes
de apóstrofos utilizados dentro da sequência de caracteres de uma ou mais dimensões.
delimitada entre aspas inglesas (“). No entanto a variável Os tipos de dados existentes na linguagem de programação
TEXTO2 está a ser atribuída com o valor da sequência de lua não necessitam de ser explicitamente definidos para
caracteres 'Utilize a tecla \'<Enter>\''. Neste caso para poder recorrer a sua utilização (por serem tipos dinâmicos) como
fazer uso de aspas simples dentro da sequência de ocorre, por exemplo, nas linguagens de programação Pascal,
caracteres foi necessário o uso dos caracteres especiais \' C, C++ entre outras.
entre a palavra <Enter> para que o carácter apóstrofo seja Além da definição e uso de variáveis para a elaboração de
adequadamente apresentado. programas, há também a necessidade de recorrer a
Uma sequência de caracteres pode ser delimitada também constantes. Uma constante está normalmente associada à
entre parêntesis duplos ([[texto]]). Assim sendo, pode-se definição de valores pré-existentes, como valores que dão
definir uma sequência de caracteres entre parêntesis duplos peso e equilíbrio em fórmulas e expressões matemáticas.
como: Constante será a definição de um valor que ficará inalterado
durante a execução de um programa.
TEXTO3
TEXTO3= [[Utilize a tecla '<Enter>']]
= [[Utilize a tecla '<Enter>']]
Operadores e Expressões Aritméticas
Ou pode-se ainda definir uma sequência de caracteres com Os operadores aritméticos são ferramentas responsáveis por
parêntesis duplos como: permitir a elaboração e execução de cálculos matemáticos
numa determinada linguagem de programação. Para se
utilizar destes operadores é necessário fazer uso de variáveis
TEXTO3
TEXTO3 = [[Utilize
= [[Utilize
e constantes.
a tecla
a tecla
Os operadores aritméticos podem ser classificados em duas
'<Enter>']]
'<Enter>']]
categorias: binários ou unários. São binários quando actuam
em operações de exponenciação, radiciação, multiplicação,
divisão, adição e subtracção. São unários quando actuam na
Neste caso a mensagem será escrita em três linhas de texto inversão da forma como um valor numérico será
exactamente como está definida na sequência de interpretado, atribuindo a este valor numérico o sinal
caracteres. positivo ou negativo.
O tipo function é usado no sentido de representar valores A tabela seguinte apresenta um resumo dos operadores
que podem ser atribuídos a uma determinada variável que aritméticos utilizados e quais as operações matemáticas que
sejam passados como parâmetros. Como exemplo básico de podem ser executadas na linguagem de programação LUA:
uso deste tipo de dados considere o seguinte:
functionnome_função()
function nome_funçao(parametro)
acçao
end
end
variável = nome_funçao(parametro)
nome_função()
<26>
a programar
<27>
a programar
de dados via teclado) e io.write() ou print() (para a saída de uso ou *line para fazer a leitura da próxima linha de um
dados em monitor de vídeo - ecrã). arquivo em uso. Nesta etapa de aprendizagem será
Para a saída de dados a linguagem Lua disponibiliza a concentrado o estudo apenas sobre o parâmetro *number.
possibilidade de uso de duas instruções, sendo io.wirite() A quarta linha de código estabelece o uso de um
utilizado quando se deseja em média manter o cursor processamento matemático, cuja acção efectua a adição
posicionado na mesma linha (pode-se alterar o cursor de dos valores armazenados nas variáveis A e B e efectua a
linha se utilizado a sequencia de \n) após a apresentação de atribuição do resultado da adição dentro da variável X.
um determinado conteúdo, ou print() quando se deseja que A quinta linha do programa faz a saída do conteúdo
o cursor seja posicionado na linha seguinte após a armazenado na variável X por meio da acção anterior de
apresentação do conteúdo. processamento. Note que além da indicação da variável X,
Nas instruções io.read() e io.write() têm na sua composição há também a definição da sequência de especial \n no
a definição de dois seguimentos separados por ponto. Note sentido de avançar uma linha em branco após a
que o primeiro seguimento de cada instrução é formado por apresentação da saída do programa.
io (input/output) que informa que os comandos read e write Observe no programa progr01.lua o uso dos conceitos de
pertencem a uma biblioteca denominada io (biblioteca de entrada, processamento e saída para a acção pretendida
entrada e saída). pelo programa. As figuras 2.1 e 2.2 mostram
Para colocar em prática o exposto até este momento, respectivamente a listagem do código e a execução do
considere o desenvolvimento de um programa que efectue a programa após o uso da chamada:
leitura de dois valores numéricos, faça em seguida a
operação de adição (processamento matemático) dos dois
valores lidos e apresente como saída o resultado obtido da lua5.1 progr01.lua
lua5.1 progr01.lua
adição processada. Considere o código:
./lua5.1 progr01.lua
./lua5.1 progr01.lua
-- --
inicio do programa
inicio ADICIONA NUMEROS
do programa ADICIONA NUMEROS
A = io.read("*number")
A = io.read("*number")
B = io.read("*number")
B = io.read("*number")
X = AX+ B= A + B Perceba que na execução do programa é apresentado um
io.write(X, "\n")
io.write(X, "\n") cursor piscando no ecrã. Forneça o primeiro valor numérico.
-- --
fim do
fimprograma ADICIONAADICIONA
do programa NUMEROS NUMEROS Introduza o valor 5 e pressione a tecla <Enter>.Na sequência
entre um segundo valor, introduza o valor 4.5 e pressione a
tecla <Enter>. Perceba em seguida a apresentação do
Em seguida escreva o código do programa anterior num resultado será 9.5.
editor de texto da sua preferência, gravando-o com o nome Apesar do programa progr01.lua apresentar correctamente
progr01.lua. o valor da soma, não interage adequadamente com o seu
Observe que o código do programa progr01.lua é formado utilizador. Para melhorar a legibilidade do programa com o
por seis linhas. Cada linha representa a definição de uma seu utilizador é necessário fazer algumas alterações.
instrução de execução de uma determinada acção Observe as linhas em negrito inseridas no código:
computacional.
A primeira e a última linha de código, indicadas pelo uso dos
-- inicio do programa ADICIONA NUMEROS
caracteres traços duplos, são usadas no sentido de definir -- inicio do programa ADICIONA NUMEROS
linhas de comentários. O uso de linhas de comentários
io.write("Entre o 1o. valor: " )
permite a possibilidade de se fazer a documentação de io.write("Entre o 1o. valor: ")
A = io.read("*number")
informações consideradas importantes. No exemplo A = io.read("*number")
io.write("Entre o 2o. valor: " )
apresentado as linhas de comentários indicam o início e o io.write("Entre o 2o. valor: ")
B = io.read("*number")
fim do programa ADICIONA NUMEROS. B = io.read("*number")
X = A + B
A segunda e terceira linhas estão a ser utilizadas no sentido X=A+B
io.write("O resultado da soma
de efectivarem as instruções de entrada dos valores io.write("O resultado da soma equivale a: ", X, "\n")
equivale a: ", X, "\n")
numéricos e de transferirem estes valores respectivamente
para as variáveis A e B. Observe que para efectivar a entrada -- fim do programa ADICIONA NUMEROS
-- fim do programa ADICIONA NUMEROS
de dados está a ser utilizado o comando io.read() com o
parâmetro *number entre aspas informando que o
conteúdo a ser armazenado na variável, que é um dado de Grave a nova versão do programa com o nome progr02.lua e
tipo numérico e que poderá ser do tipo inteiro ou real. Se o em seguida execute na linha de comando (para Windows e
parâmetro *number for omitido, o interpretador entenderá Linux respectivamente):
que a entrada de dados é um valor do tipo alfanumérico.
Além do parâmetro *number pode-se também fazer uso dos
lua5.1 progr02.lua
parâmetros *all para fazer a leitura de um arquivo inteiro em lua5.1 progr02.lua
<28>
a programar
<29>
a programar
augusto.manzano@portugal-a-programar.org
Augusto Manzano
<30>
a programar
<31>
a programar
<32>
a programar
Mas o poder dos templates surge quando incluímos blocos aplicações (ou mesmo no decorrer de um projecto
de código e dados dinâmicos, como por exemplo: concreto), há sempre padrões de construção que
encontramos e que tentamos tornar mais coerente
efectuando um refactoring para maximizar o
<#@ Template Language="C#v3.5" #> reaproveitamento de código e a organização dos objectos
<#@ Import Namespace="System" #> segundo padrões de POO.
<#@ Output Extension=".html" #>
<html> Mesmo assim, há estruturas que ultrapassam a estrutura de
<body> objectos, como nomes, tipos de dados, descrições,
Olá Mundo! Fui criado às < #= mapeamento de campos, etc. Um domínio especifico pode
DateTime.Now.ToString( "HH:mm") #> ter uma forma coerente de construir objectos com estes
<body> parâmetros, e um gerador de código pode ser usado para
</html> criar o código do domínio automaticamente. Imagina uma
aplicação de n-camadas, com UI, Camada de negócios,
Camada de acesso a dados, e a própria estrutura de
que resulta em: armazenamento de dados. Tem regras próprias, que em
alguns casos podem ser generalizadas, mas as
características dos objectos do domínio não são genéricas.
<html> Com o gerador de código podemos cria-los e a
<body> funcionalidade associada automaticamente!
Olá Mundo! Fui criado às 20:15
<body>
</html> Vou então pegar neste exemplo, simplificado, para
demonstrar o potencial do gerador. Vou considerar a
seguinte estrutura:
Temos assim um exemplo de um timestamp num ficheiro
• A minha base de dados é um conjunto de tabelas
gerado automaticamente. Este exemplo apresenta um novo
com colunas simples (vou omitir relações pela simplicidade e
bloco de código. Há 4 tipos de blocos:
podermos concentrar no T4)
<#+ Adiciona “class features” ao código, permitindo Com o gerador de código vou tentar criar o SQL de criação
criar métodos e classes reutilizáveis nos da base de dados, alguns métodos da DAL, e as classes BO.
templates
<33>
a programar
#>
<34>
a programar
<35>
a programar
O template gerou assim o código do objecto com os campos Repara que, a partir da mesma definição, foi possível criar
privados e as propriedades publicas, getters e setters dois ficheiros de código de tipos diferentes, baseados
incluídos. Podia ainda incluir atributos de serialização, maioritariamente em parâmetros comuns. Neste caso
comentários de descrição, etc. Quaisquer dados necessários definimos a saída do tipo .sql. Um ficheiro SQL deste tipo
devem ser colocados nos metadados e usados pelo template teria o script de criação da base, incluindo relações a
para incluír no código com a formatação desejada. adicionar, sequências, stored procedures base, etc. O
template que gerei foi direccionado para SQL server, mas
podia perfeitamente direccionar a outro SGBD ou até criar
Definir script da base de dados mais um template dedicado a outra base de dados.
Definir o acesso a dados
Vamos gerar SQL agora, para criar a tabela na base de
dados: Para a DAL, teremos essencialmente uma classe com um
conjunto de métodos que implementa métodos CRUD
comuns como obter um registo por um ID, uma lista por um
conjunto de parâmetros, número de registos por
<#@ Template Language= "C#v3.5" #>
parâmetros, inserção e actualização de registos,
<#@ Import Namespace= "System" #>
actualização determinado campo de um registo ou ainda
<#@ Import
apagar registos. Deve ainda ser capaz de mapear os dados
Namespace="System.Collections.Generic"
dos campos da base de dados para as propriedades dos
#>
objectos respectivos. No exemplo que segue, demonstro
<#@ Output Extension= ".sql" #>
uma versão simples de acesso a um registo e preenchimento
<#@ Include File="Loader.t4" #>
de um objecto:
<#@ Include File="Classes.t4" #>
<#
ObjectoSimplesDAL.tt
MinhaClasse minhaClasse =
Loader.CarregarDefinicao();
<#@ Template Language= "C#v3.5" #>
#>
<#@ Import Namespace="System" #>
CREATE TABLE <#= minhaClasse.Nome #>
<#@ Import
{
Namespace="System.Collections.Generic"
<#
#>
for (int i = 0; i <
<#@ Output Extension=".cs" #>
minhaClasse.Propriedades.Count; i++ )
<#@ Include File="Loader.t4" #>
{
<#@ Include File="Classes.t4" #>
MinhaPropriedade propriedade
<#
= minhaClasse.Propriedades[i];
MinhaClasse minhaClasse =
#>
Loader.CarregarDefinicao();
<#= propriedade.Nome #> <#=
#>
propriedade.TipoDB #> <#=
using System;
propriedade.IsPK ? "PRIMARY KEY" : ""
using ClassesGenericasDeAcessoADados;
#><#=
i<minhaClasse.Propriedades.Count-1 ?
public class <#= minhaClasse.Nome
"," : "" #>
#>DAL
<#
{
}
/// <summary>
#>
/// Retorna um objecto do tipo <#=
}
minhaClasse.Nome #> a partir da chave
/// </summary>
<#
que gera:
MinhaPropriedade chave = null;
foreach (MinhaPropriedade prop
CREATE TABLE ObjectoSimples in minhaClasse.Propriedades)
{ {
id int PRIMARY KEY, if (prop.IsPK)
nome varchar(100) , {
funcao text chave = prop;
} break;
}
<36>
a programar
propriedade.Nome #>"))
}
obj.<#=
#>
propriedade.Nome #> =
/// <param name="<#= chave.Nome
dataParser.DRGet<#= propriedade.TipoCS
#>">ID a pesquisar</param>
#>("<#= propriedade.Nome #>" );
/// <returns></returns>
<#
public <#= minhaClasse.Nome #>
}
GetItem(<#= chave.TipoCS #> <#=
#>
chave.Nome.ToLower() #>)
}
{
string sqlQuery = "SELECT *
return obj;
FROM <#= minhaClasse.Nome #> WHERE <#=
}
chave.Nome #> = " + <#=
}
chave.Nome.ToLower() #>;
try
{ que resulta em:
using(DataAccessor
dataAccessor = new
DataAccessor(connectionString) ) using System;
return (<#= using ClassesGenericasDeAcessoADados;
minhaClasse.Nome
#>)dataAccessor.GetDBObject(sqlQuery, public class ObjectoSimplesDAL
FillObject); {
}
catch(Exception e) /// <summary>
{ /// Retorna um objecto do tipo
//código de logging ObjectoSimples a partir da chave
} /// </summary>
} /// <param name="id">ID a
pesquisar</param>
/// <summary> /// <returns></returns>
/// Preenche <#= public ObjectoSimples GetItem(int
minhaClasse.Nome #> com os dados id)
provenientes da base {
/// </summary> string sqlQuery = "SELECT *
/// <param FROM ObjectoSimples WHERE id = " + id;
name="data">IDataReader com os dados
recebidos</param> try
/// <returns></returns> {
public static <#= minhaClasse.Nome using(DataAccessor
#> FillObject(IDataReader data) dataAccessor = new
{ DataAccessor(connectionString) )
<#= minhaClasse.Nome #> obj = return
new <#= minhaClasse.Nome #>(); (ObjectoSimples)dataAccessor. GetDBObjec
t(sqlQuery, FillObject);
using (DataParser dataParser = }
new DataParser(data)) catch(Exception e)
{ {
<# //código de logging
foreach(MinhaPropriedade }
propriedade in }
minhaClasse.Propriedades)
{ /// <summary>
#> /// Preenche ObjectoSimples
if (dataParser.IsValid<#= com os dados provenientes da base
propriedade.TipoCS #>("<#= /// </summary>
/// <param
<37>
a programar
Repare que foi possível uniformizar os comentários XML public override string
para documentação, que ficam simples de manter, e ainda TransformText() {
uniformizar a estrutura de de acesso a dados. DataAccessor try {
é um objecto com operações genericas (como o this.Write("\r\n");
getDBObject) implementadas no namespace this.Write("\r\n");
“ClassesGenericasDeAcessoADados”. GetDBObject está this.Write("\r\n<html>\
intergrado nesse objecto, executa uma query na base, e r\n <body>\r\n Olá Mundo! Fui
devolve um objecto preenchido através do método criado às ");
delegado FillObject.
this.Write(Microsoft.VisualStudio.TextT
FillObject também é criado no template e integrado na emplating.ToStringHelper. ToStringWithCu
classe da DAL. Essencialmente, utiliza uma classe lture(DateTime.Now.ToString("HH:mm")));
DataParser com alguns métodos de validação e obtenção de
dados, preenchendo as propriedade de ObjectoSimples com this.Write("\r\n
os dados das colunas respectivas. <body>\r\n</html>\r\n\r\n");
}
Com estas classes já geradas, podíamos perfeitamente catch (System.Exception e)
compilar os ficheiros num projecto de DLL e incluí-lo em {
aplicações que pretendemos construir para o domínio dos System.CodeDom.Compiler
nossos objectos. Quaisquer alterações ao domínio, evolveria .CompilerError error = new
apenas regenerar os ficheiros e recompilar, substituindo a System.CodeDom.Compiler. CompilerError()
.dll original. ;
error.ErrorText =
e.ToString();
<38>
a programar
Repara que foi gerado um namespace temporário e incluído Também não estamos limitados a um ficheiro de saída por
as referências das directivas. Foi criado uma classe com o template. Apesar de não suportado directamente, há
nome do nosso ficheiro e que herda de exemplos de métodos a incluir que permite guardar o
Microsoft.VisualStudio.TextTemplating.TextTransormation. conjunto de texto gerado até determinado momento num
Esta classe tem um método TransformText() ao qual é feito ficheiro. Com um template, é possível percorrer todos os
um overide. A nova definição do método inclui o texto do objectos do domínio e criar uma classe BO, DAL, BLL, e
nosso template. Repare que o texto escrito fora dos blocos documentação para cada um, com cada bloco gerado num
<# #> é inserido em métodos Write(). Texto em blocos de ficheiro independente e integrado no projecto. Esta solução
expressões <#= #> é inserido num Write() como valor de e muitas outras estão descritas por Oleg Sych no blog dele,
retorno do Microsoft.VisualStudio.TextTemplating. e incluído no T4 Toolkit que ele desenvolveu. O blog deste
ToStringHelper.ToStringWithCulture(). Qualquer código em autor é actualmente, e na minha opinião, a melhor fonte de
blocos <# #> é inserido no método TransformText() como informação acerca dos templates T4 e o T4 Toolkit e os
código do mesmo. Podemos adicionar mais métodos a esta exemplos apresentados são valiosos para maximizar o
classe (HelloWorld) usando o controlo <#+ #>, como aproveitamento.
métodos auxiliares, ou novas classes se as definirmos em
blocos <#+ #> de ficheiros externos incluídos pela directiva Uma outra forma de maximizar a potencialidade é construir
<#@ Include #>. uma DSL (Domain Specific Language). A Microsoft
disponibiliza os Visual Studio DSL Tools para construir DSLs
gráficos, integrados no VS, melhorando a experiência de
Esta classe é, depois de criada, instanciada pelo motor de produzir os metadados. O Class Designer já existente no VS
processamento e o método TranformText() é chamado para é um bom exemplo de uma DSL integrada. Um bom livro a
criar o ficheiro resultante. O acesso a recursos é controlado seguir é o “Domain Specific Development with Visual Studio
por uma entidade conhecida por ‘Host’ que o motor de DSL Tools”. Não é um tema leve, mas as potencialidades
processamento utiliza sempre que necessita de aceder ao justificam o esforço. O blog do Hugo Ribeiro também é uma
ambiente aplicacional. À partida temos apenas um host boa fonte de dados.
incluído na API de extensibilidade do VS.
Por fim, é importante referir que o Visual Studio tem um
“defeito” relacionado com os templates T4. Não inclui
Com o host original, o template já é bastante funcional e suporte de cor e intelisense à sintaxe dos templates. A falta
poderoso. Mas é extraordinário quando construímos os de coloração e instelisense torna a produção dos templates
nossos próprios hosts e processadores. A possibilidade de o um processo duro. Felizmente há um add-in chamado T4-
motor de processamento interagir com os nossos Hosts editor, criado pela Clarius Consulting, que existe na versão
permite-nos definir estruturas de metadados próprias do Profissional e comunitária (gratuita mas com algumas
domínio em que estamos a trabalhar, com validação e limitações). A versão profissional é bastante em conta (cerca
ferramentas mais eficientes na produção das mesmas. A de 90 euros) e justifica o custo facilmente. No mínimo,
mesma estrutura de classes rudimentar que definimos no justifica integrar a versão comunitária para melhorar a
exemplo pode ser construído e estendido numa DSL experiência.
(Domain Specific Language) e gerado uma ferramenta de
trabalho para criar o ficheiro de definições para a mesma. O
host gerado alimentará o motor com a informação
necessária para construirmos código ou outro tipo de
recurso necessário.
<39>
a programar
miguel.alho@portugal-a-programar.org
Miguel Alho
<40>
Queres participar na Revista
PROGRAMAR? Queres integrar este
projecto, escrever artigos e ajudar a
tornar esta revista num marco da
programação nacional?
Vai a
www.revista-programar.info
para mais informações em como
participar,
ou então contacta-nos por
revistaprogramar
@portugal-a-programar.org
Precisamos do apoio de todos para
tornar este projecto ainda maior...
Equipa PROGRAMAR
Um projecto Portugal-a-Programar.org
<41>