Pessoalmente gosto muito de coisas heréticas ou subversivas. Sou um apaixonado por subversão. =D
Olhando a documentação, podemos ver que Seaside é suportado pelas máquinas virtuais Cincom VisualWorks, GNU Smalltalk, VA Smalltalk, Squeak e seus derivados Pharo e GLASS.
GNU Smalltalk
A máquina virtual recomentada é Squeak, da qual gosto muito e que é ótima para aplicações desktop, no entanto Squeak é uma plataforma muito pesada, consome muitos recursos da máquina, por isso, para Seaside, optei por uma plataforma mais leve: GNU Smalltalk.
GNU Smalltalk sofre porém de um mal extremamente irritante: a sintaxe da linguagem é muito irregular – para ser eufémico.
Teoricamente GNU Smalltalk suportaria a sintaxe correta de Smalltalk-80, mas não funciona bem assim… ele é muito chato e levanta erros de sintaxe para códigos perfeitamente corretos, mas que diferem do que o GNU Smalltalk espera de Smalltalk-80. Então é preciso experimentar algumas formas diferentes – mas regulares – de fazer as coisas antes de encontrar uma que funcione (às vezes ele implica até com nomes de argumentos).
Vou usar aqui a sintaxe Smalltalk-80 precisa – e que funciona no GNU Smalltalk –, mas colocarei o mesmo código na sintaxe peculiar do GNU Smalltalk ao final deste artigo apenas por curiosidade.
Preparação da imagem
Para criar a imagem para nosso exemplo usei o comando:
bash$ gst-load -iI seaside.im Seaside Seaside-Development Seaside-Examples
Isso cria uma imagem
seaside.im
com os pacotes Seaside
(Seaside em si), Seaside-Development
(ferramentas de desenvolvimento) e Seaside-Examples
(exemplos).Usei então o exemplo de componente da própria documentação:
MyCounter.st
.- O método de classe
#canBeRoot
diz se o componente pode ser registrado como uma aplicação autónoma ou não. - Na inicialização (
#initialize
) o atributocount
é zerado. - O método
#states
retorna uma coleção de estados que podem ser retrilhados (backtracked). - O método
#renderContentOn:
é usado para renderizar a página. - Ao final a mensagem
#registerAsApplication:
registra o componente como aplicação.
O código fica então (se copiar e colar, substituia
↑
por ^
):" See: http://www.gnu.org/software/smalltalk/manual/html_node/Seaside.html "
Seaside.WAComponent subclass: #MyCounter
instanceVariableNames: 'count'
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside Examples'
!
!MyCounter class methodsFor: 'testing'!
canBeRoot
↑true
!
!
!MyCounter methodsFor: 'initializing'!
initialize
super initialize.
count := 0.
!
!
!MyCounter methodsFor: 'accessing'!
states
↑{ self }
!
!
!MyCounter methodsFor: 'rendering'!
renderContentOn: html
html heading: count.
html anchor
callback: [ count := count + 1 ];
with: '++'.
html space.
html anchor
callback: [ count := count - 1 ];
with: '--'.
!
!
MyCounter registerAsApplication: 'mycounter'.
Para carregar o componente na imagem usei o comando:
bash$ gst -I seaside.im -S MyCounter.st
Rodar a aplicação
O seguinte comando levanta a máquina virtual no modo servidor:
bash$ gst-remote -I seaside.im --daemon
Depois disso você poderá ver a máquina virtual ouvindo na porta 12345/TCP:
bash$ netstat -ln4 | grep 12345
tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTEN
É possível obter o PID do processo da máquina virtual com seguinte comando:
bash$ gst-remote --pid
Porém o Seaside não está rodando. Para rodar o serviço web use o comando:
bash$ gst-remote --start=Seaside
É possível também iniciar a máquina virtual já rodando o Seaside com o seguinte comando:
bash$ gst-remote -I seaside.im --daemon --start=Seaside
Por padrão o serviço web Seaside estará escutando na porta 8080/TCP.
Para acessar a aplicação que acabamos de criar use o endereço http://localhost:8080/seaside/mycounter.
Parar a aplicação
Para parar a aplicação use o comando:
bash$ gst-remote --stop=Seaside
Repare que, apesar do serviço web ter parado, a máquina virtual continua rodando. Para pará-la:
bash$ gst-remote --kill
Para comparação
A título de comparação, segue o código usando a sintaxe
Seaside.WAComponent subclass: MyCounter [
| count |
<category: 'Seaside Examples'>
<comment: nil>
MyCounter class >> canBeRoot [
<category: 'testing'>
^true
]
initialize [
<category: 'initializing'>
super initialize.
count := 0
]
states [
<category: 'accessing'>
^{ self }
]
renderContentOn: html [
<category: 'rendering'>
html heading: count.
(html anchor)
callback: [count := count + 1];
with: '++'.
html space.
(html anchor)
callback: [count := count - 1];
with: '--'
]
].
MyCounter registerAsApplication: 'mycounter'.
[]'s
Cacilhas, La Batalema