Entradas categorizadas em ‘Smalltalk’
Resolvi implementar um camel case stripper em Smalltalk (Pharo). Talvez fosse mais fácil fazê-lo usando expressões regulares mas usei técnicas de parsing. Veja o código abaixo:
Criando a class:
Object subclass: #CamelCaseStripper
instanceVariableNames: 'read word char write'
classVariableNames: ''
poolDictionaries: ''
category: 'FAM-Utils'
O método principal:
strip
"Ver CamelCaseStripper example"
self readChar.
self readWord.
[word isEmptyOrNil] whileFalse: [
write add: word.
self readWord.
].
^write asArray
A lógica para separar as ‘corcovas’:
readWord
| wordWrite |
wordWrite := WriteStream on: String new.
char ifNotNil:
[ char isLowercase
ifTrue: [ self writeLowercaseTo: wordWrite ]
ifFalse: [ "Uppercase"
wordWrite nextPut: char.
self readChar.
char ifNotNil: [
char isUppercase ifTrue: [
self writeUppercaseTo: wordWrite]
ifFalse: [
self writeLowercaseTo: wordWrite
]
]
]
].
word := wordWrite contents
E, finalmente, os métodos chamados:
writeLowercaseTo: wordWrite
[ char notNil and: [ char isLowercase ] ] whileTrue:
[ wordWrite nextPut: char.
self readChar ]
e
writeUppercaseTo: wordWrite
[ char notNil and: [ char isUppercase ] and: [self nextChar isUppercase]] whileTrue:
[ wordWrite nextPut: char.
self readChar ]
No class side veja como usar a classe:
example
|stripper|
stripper := CamelCaseStripper from: 'prefixWABrushTag'.
stripper strip "--> #('prefix' 'WA' 'Brush' 'Tag')"
Outros detalhes podem ser vistos em CamelCaseStripper.st.
Coloquei também um método de conveniência em String:
camelCaseStrip
^(CamelCaseStripper from: self) strip
Agora o uso fica como a seguir:
'ABCdefGHIjk' camelCaseStrip "--> #('AB' 'Cdef' 'GH' 'Ijk')"
Nota: Estou usando o site http://www.hilite.me/ para code beautifier mas não estou gostando das barras de rolagem horizontais. Acho que a identação do hilite me é exagerada. No futuro vou tentar usar http://pastie.org (acho que precisa de um plugin para o WordPress: Show Pastie Code in Comments WordPress Plugin).
Categorias: Smalltalk
Para começar a experimentação com a linguagem Newspeak e o IDE estou lendo Newspeak on Squeak A Guide for the Perplexed. Com é de praxe a construção de um hello world evita complicações com o código para um ‘newbie’. Vamos então ao HelloBraveNewWorld!
O ambiente para o Mac baixei em Newspeak Prototype Release.
O Hopscotch é o IDE (ou um IDE) para Newspeak.

Um característica das GUI no Newspeak é poder ser navegada no estilo Web. Parece ser mais produtivo do que o esquema baseado no Class Browser do Smalltalk. Já tinha visto algo assim no ambiente do Eiffel.
Entrei também no Newspeak Forums (no forum fui informado sobre como remover uma categoria).
Seguindo o link ‘System Source’ obtemos:

Clicando no link ‘add’ ao lado de ‘(unpackaged)’ podemos criar a categoria:

Clicando no botão verde a categoria é criada:

Navegando pelo link ‘Nspk-example’ temos:

Clicando no ‘+’ é possível criar uma classe:

Que alteramos para:

NewspeakObject é uma classe que substituiu Object e apresenta uma API mais enxuta.
(Continua na parte 2)
Categorias: Smalltalk · Tecnologia
Andei experimentando um pouco com SandstoneDb, uma solução de persistência similar à do Prevayler.
Criei uma classe User:

O método para criação dos objetos User:

A linhas abaixo servem para criar um objeto User e armazená-lo na imagem, encontrar o objeto através de uma query e removê-lo e as duas últimas para exibí-los:

Para que a exibição de um objeto User seja legível é preciso implementar o método:

Pretendo ainda investigar como a coisa funciona para objetos mais complexos.
Categorias: Smalltalk

É aparentemente estranho que uma abordagem procedural baseada em Basic seja desenvolvida em Smalltalk no topo do Seaside e para construção de aplicações Web. Mas esta é a proposta do Run Basic. Baixei aqui no Mac para dar uma pequena olhada. Já fui hacker de Basic desde o tempo dos teclados de membrana no Sinclair (TK 85) e depois no MSX. Mas como há muito tempo não uso o Basic espero que os manuais no site sejam suficientes para dar uma fuçada básica. Uma das primeiras coisas que quero testar é a sua integração com o Sqlite(3).
Criei um banco de dados com o código abaixo (antes criei a pasta db usando o Finder):


Embora eu tenha colocado o código fonte em um editor para melhor capturar a imagem, tudo no Run Basic acontece no web browser.
A estrutura dos programas está me fazendo lembrar de um framework chamado Eleven.
Boa parte dos projetos exemplo trabalham com um único arquivo. Encontrei runWiki que tem mais de um arquivo .bas na sua pasta mas parece que os outros arquivos são versões anteriores do arquivo runWiki.bas.
Categorias: Smalltalk · Tecnologia · Web
Chegou hoje o livro ‘An Introduction to Seaside’:

Categorias: Livro · Smalltalk · Software · Tecnologia

Este hack mostra como usar #onAnswer. Para mais detalhes veja o link lá embaixo.
Criaremos 4 classe e seus métodos para obter imagens fáceis de seguir.
Crie a primeira classe com o código:
SeasideHack subclass: #OnAnswerHack
instanceVariableNames: ‘a’
classVariableNames: ”
poolDictionaries: ”
category: ‘Seaside-Hacks’
E os métodos:
initialize
super initialize.
a := A new
renderContentOn: html
html render: a
children
^ Array with: a
Crie a segunda classe com:
SeasideHack subclass: #A
instanceVariableNames: ”
classVariableNames: ”
poolDictionaries: ”
category: ‘Seaside-Hacks’
E os métodos:
renderContentOn: html
html div id: ‘letter-A’;
with: [html text: 'A'.
html
form: [html submitButton text: 'call B';
callback: [self call: B new]]]
style
^ ‘#letter-A {background-color: hotpink; width: 300px; height: 300px}’
Crie a terceira classe com:
SeasideHack subclass: #B
instanceVariableNames: ‘c’
classVariableNames: ”
poolDictionaries: ”
category: ‘Seaside-Hacks’
Com os métodos:
initialize
super initialize.
c := C new
renderContentOn: html
html div id: ‘letter-B’;
with: [html text: 'B'.
html render: c.
html
form: [html submitButton text: 'answer';
callback: [self answer]]]
style
^ ‘#letter-B {background-color: darkseagreen; width: 200px; height: 200px}’
children
^ Array with: c
E finalmente a quarta classe:
SeasideHack subclass: #C
instanceVariableNames: ”
classVariableNames: ”
poolDictionaries: ”
category: ‘Seaside-Hacks’
E os métodos:
renderContentOn: html
html div id: ‘letter-C’;
with: [html text: 'C'.
html
form: [html submitButton text: 'answer';
callback: [self answer]]]
style
^ ‘#letter-C {background-color: aquamarine; width: 100px; height: 100px}’
Para registrar a aplicação no Seaside execute:
OnAnswerHack registerAsApplication: ‘onanswerhack’
A execução da aplicação leva à aparição da seguinte figura:

Um clique no botão call B substitui o componente A pelo componente B e faz aparecer a figura:

O botão answer do componente B (botão de baixo) invoca self answer que retorna ao componente A, mas o botão answer no componente C, embedded em B, envia a mensagem self answer que não retorna para nenhum componente pois o componente C não foi invocado com self call:. No componente B a última linha do código abaixo (que você deve inserir agora) serve para interceptar o retorno e redirecioná-lo para o componente que invocou o componente B (o componente A):
initialize
super initialize.
c := C new.
c
onAnswer: [:dummy | self answer]
Fonte: Aprendendo a usar o método #onAnswer: em Seaside na prática: autenticação de usuários
Categorias: Smalltalk
Etiquetado: hack, Seaside

WAAlphabeticBatchedList efetua a paginação de uma lista de forma alfabética.
Para testar crie a classe com o código:
WAComponent subclass: #AlphabeticBatchedListHack
instanceVariableNames: ‘items batchedlist’
classVariableNames: ”
poolDictionaries: ”
category: ‘Seaside-Hacks’
Os métodos são:
initialize
super initialize.
items := Collection allSubclasses..
batchedlist := WAAlphabeticBatchedList new.
batchedlist items: items
renderContentOn: html
html heading: self class description.
html heading: ‘All subclasses of Collection’ level: 2.
batchedlist batch
do: [:item | html render: item. html break].
html render: batchedlist
children
^ Array with: batchedlist
A página apresentada é como abaixo:

Categorias: Smalltalk
Etiquetado: hack, Seaside
Neste hack colocamos alguns códigos que podem esclarecer como usar o componente WABatchedList no Seaside. Primeiro crie a classe de teste com:
WAComponent subclass: #BatchedListHack
instanceVariableNames: ‘items batchedlist’
classVariableNames: ”
poolDictionaries: ”
category: ‘Seaside-Hacks’
Depois implemente os seguintes métodos:
initialize
super initialize.
items := OrderedCollection new.
1
to: 100
do: [:k | items add: 'item ' , (k asString padded: #left to: 3 with: $0)].
batchedlist := WABatchedList new.
batchedlist batchSize: 15.
batchedlist items: items
renderContentOn: html
html heading: ‘Batched List Test’.
batchedlist batch
do: [:item |
html render: item.
html break].
html render: batchedlist
children
^ Array with: batchedlist
A página gerada é como abaixo:

Categorias: Smalltalk
Etiquetado: hack, Seaside