GOF Patterns in Ruby

Giù al RomeCamp ci siamo ingarellati io, Kia, Giovanni e Bard a
discutere se i pattern fossero na roba seria o solo una soluzione a
problemi espressivi del linguaggio su cui si usano…
Ovviamente si parlava di Java e affini. Ho scoperto solo ora questo
link:

http://wiki.rubygarden.org/Ruby/page/show/ExampleDesignPatternsInRuby

dove spiegano i GOF in Ruby. Mò me lo leggo… voi che ne pensate?
Quante volte avete effettivamente utilizzato dei pattern in ruby?
quali?
La situazione peggiora in Rails visto che l’80% delle applicazioni è
leggi/scrivi… Ma magari c’è qualche contesto dove sono +
interessanti/utili.

Lancio il sasso giusto per aprire un confronto… in che casi
utilizzate gli observer di ActiveRecord? Avete mai avuto bisogno di
utilizzare Observer cross-model tipo gli sweeper della cache?


Paolo D.’
SeeSaw | Another point of view

[email protected]
personal http://paolodona.blogspot.com

Personalmente ritengo che la conoscenza di cosa sia un pattern, di come
si applica e del concetto di “refactoring to pattern” sia essenziale per
ogni programmatore e ingegnere del software.

    Giovanni

penso che molti bravi sviulppatori abbiano comunque un pattern instinct,
pur
non conoscendo i patterns, e credo anche che i patterns emergano dal
refactoring in modo naturale.

io li trovo impagabili per comunicare delle scelte di design ad altri
sviluppatori. I patterns sul sito indicato da Paolo non sono molto
utili in
ruby, ma di certo anche in ruby di patterns e idiomi originali ne avete
visti.

quali sono i vostri preferiti? dategli un nome :slight_smile:

Il giorno gio, 01/02/2007 alle 23.10 +0100, Paolo Donà ha scritto:

Giù al RomeCamp ci siamo ingarellati io, Kia, Giovanni e Bard a
discutere se i pattern fossero na roba seria o solo una soluzione a
problemi espressivi del linguaggio su cui si usano…
Ovviamente si parlava di Java e affini. Ho scoperto solo ora questo link:

http://wiki.rubygarden.org/Ruby/page/show/ExampleDesignPatternsInRuby

dove spiegano i GOF in Ruby. Mò me lo leggo… voi che ne pensate?
Quante volte avete effettivamente utilizzato dei pattern in ruby?
quali?

La libreria standard di Ruby implementa molti pattern:

  • #each è un esempio dell’Iterator e del Template Method
  • TestCase e TestSuite sono un esempio di Decorator

In generale, può essere utile vedere un pattern come un template per una
(possibile) soluzione ad un certo problema. Template nel senso che ogni
pattern dovrà essere adattato allo specifico problema che si vuole
risolvere.

Il pattern può essere integrato nella libreria standard, oppure deve
essere lo sviluppatore ad implementarlo, a seconda dell’espressività del
linguaggio.

Personalmente ritengo che la conoscenza di cosa sia un pattern, di come
si applica e del concetto di “refactoring to pattern” sia essenziale per
ogni programmatore e ingegnere del software.

Giovanni

penso che molti bravi sviulppatori abbiano comunque un pattern instinct, pur
non conoscendo i patterns, e credo anche che i patterns emergano dal
refactoring in modo naturale.

+1

Quando ho visto per la prima volta il libro sul “refactoring”, mi sono
detto “ah… fossi stato cosi` sveglio io a tirare fuori un libro
delle conoscenze che dovrebbero avere tutti gli sviluppatori”.


David N. Welton

Linux, Open Source Consulting

Il giorno ven, 02/02/2007 alle 00.09 +0100, chiaro scuro ha scritto:

Personalmente ritengo che la conoscenza di cosa sia un pattern, di come
si applica e del concetto di “refactoring to pattern” sia essenziale per
ogni programmatore e ingegnere del software.

    Giovanni

penso che molti bravi sviulppatori abbiano comunque un pattern instinct, pur
non conoscendo i patterns, e credo anche che i patterns emergano dal
refactoring in modo naturale.

Sono d’accordo. Però saper fare queste cose in maniera esplicita
piuttosto che instintiva spesso ti dà una marcia in più.

io li trovo impagabili per comunicare delle scelte di design ad altri
sviluppatori. I patterns sul sito indicato da Paolo non sono molto utili in
ruby, ma di certo anche in ruby di patterns e idiomi originali ne avete
visti.

Non penso che non siano molto utili. Tempo fa mi sono dedicato alla
scrittura di un piccolo text editor, come esercizio per imparare le
librerie Ruby-Gnome2, ed ho usato vari pattern presenti in quella lista.

Giovanni

ne approfitto per girare un link a chi non conoscesse ancora i pattern:
http://www2.ing.puc.cl/~jnavon/IIC2142/patexamples.htm

è una carrellata rapida e divertente, con esempi molto concreti

On 2/2/07, Giovanni C. [email protected] wrote:

penso che molti bravi sviulppatori abbiano comunque un pattern instinct,
pur

Sono d’accordo. Però saper fare queste cose in maniera esplicita
piuttosto che instintiva spesso ti dà una marcia in più.

si, vero. aggiungo però che la grande sfida poi però è dimenticarseli e
riaffidarsi all’istinto. in questo aiuta tantissimo il refactoring, per
riacquistare una certa naturalezza di movimento.

quando impari i pattern ti viene spesso da implementarli in modo
completo,
canonico… e spesso non è necessario. se li evolvi via refactoring questo
non succede ed i tuoi gesti risultano molto più fluidi e puliti.

io li trovo impagabili per comunicare delle scelte di design ad altri

sviluppatori. I patterns sul sito indicato da Paolo non sono molto
utili in
ruby, ma di certo anche in ruby di patterns e idiomi originali ne avete
visti.

Non penso che non siano molto utili. Tempo fa mi sono dedicato alla
scrittura di un piccolo text editor, come esercizio per imparare le
librerie Ruby-Gnome2, ed ho usato vari pattern presenti in quella lista.

ma non trovi che molti pattern ‘classici’ evaporino in ruby? tanti di
quei
pattern ad esempio servono per aggirare i limiti di un linguaggio
statically
typed.

On 2/2/07, Giovanni C. [email protected] wrote:

penso che molti bravi sviulppatori abbiano comunque un pattern instinct, pur
non conoscendo i patterns, e credo anche che i patterns emergano dal
refactoring in modo naturale.

Sono d’accordo. Però saper fare queste cose in maniera esplicita
piuttosto che instintiva spesso ti dà una marcia in più.

Qualche eresia da tarda ora (Paolo, tieni pronte le magiche parole
pacificatrici):

Queste cose le facciamo in maniera esplicita al posto di, non oltre a,
farle in maniera istintiva.

Il rapporto tra materiale letto e materiale scritto è, per un
programmatore, imbarazzante, al confronto del rapporto tra materiale
letto e materiale scritto, per uno scrittore.

Leggendo poco codice, ci sono poche occasioni di “assorbire”, e si
cerca di compensare con l’“imparare”, e con la pratica che, qualche
volta, riesce a diventare seconda natura.

Se si vuole scrivere un buon romanzo, un testo di grammatica e un
manuale di stile potrebbero non essere sufficiente.


Massimiliano M.
code: http://dev.hyperstruct.net
blog: http://blog.hyperstruct.net

Il giorno ven, 02/02/2007 alle 00.46 +0100, chiaro scuro ha scritto:

ne approfitto per girare un link a chi non conoscesse ancora i pattern:
http://www2.ing.puc.cl/~jnavon/IIC2142/patexamples.htm

è una carrellata rapida e divertente, con esempi molto concreti

Aggiungerei il Portland Pattern Repository: Portland Pattern Repository .

ma non trovi che molti pattern ‘classici’ evaporino in ruby? tanti di quei
pattern ad esempio servono per aggirare i limiti di un linguaggio statically
typed.

In realtà non direi. Quello che capita è che alcuni pattern siano
talmente ubiqui nella libreria standard che se non ci si fa attenzione
non si pensa ad essi come pattern. #each implementa il pattern Iterator,
ad esempio. #new implementa il Factory Method. #initialize è un Template
Method.

L’uso di un pattern può essere più evidente in un linguaggio statically
typed perché le idiosincrasie del linguaggio ti costringono ad inserire
interfacce, classi base astratte o simili che fanno risaltare il
pattern. Ad esempio in JUnit c’è un’interfaccia Test che specifica quali
metodi devono essere implementati da TestCase e TestSuite. In Test::Unit
TestCase e TestSuite derivano direttamente da Object e si limitano ad
implementare gli stessi metodi.

Giovanni

prendiamo una buona abitudine… proviamo a leggere del codice e
commentarlo.

poi possiamo mettere le review su ruby-it o su trm.

letto buon codice ultimamente? che codice vi ha colpito?

Verissimo. Non ci avevo mai pensato, ma è proprio così. Leggo molto
meno codice di romanzi e il mio lavoro è scrivere codice tutto il
giorno…
Massimiliano => EyeOpeningPost™
:slight_smile:
Massimiliano M. wrote:

 On 2/2/07, Giovanni C. [1]<[email protected]> wrote:

 > penso che molti bravi sviulppatori abbiano comunque un pattern
 instinct, pur
 > non conoscendo i patterns, e credo anche che i patterns emergano
 dal
 > refactoring in modo naturale.
 Sono d'accordo. Però saper fare queste cose in maniera esplicita
 piuttosto che instintiva spesso ti dà una marcia in 

più.
Qualche eresia da tarda ora (Paolo, tieni pronte le magiche parole
pacificatrici):
Queste cose le facciamo in maniera esplicita al posto di, non oltre
a,
farle in maniera istintiva.
Il rapporto tra materiale letto e materiale scritto è, per un
programmatore, imbarazzante, al confronto del rapporto tra
materiale
letto e materiale scritto, per uno scrittore.
Leggendo poco codice, ci sono poche occasioni di “assorbire”, e si
cerca di compensare con l’“imparare”, e con la pratica che, qualche
volta, riesce a diventare seconda natura.
Se si vuole scrivere un buon romanzo, un testo di grammatica e un
manuale di stile potrebbero non essere sufficiente.


“Remember, always be yourself. Unless you suck.” - Joss Whedon

References

  1. mailto:[email protected]

chiaro scuro ha scritto:

Il codice VBA che sto sviluppando mi ha colpito parecchio…
… come un mattone che si schianta contro il tuo muso!

ma dai che l’ho pure letto ed è leggibilissimo. è un codice onesto.

mi ricordo che mi aveva colpito il codice di ROXI di Lana, perchè essendo
scritto in C ed essendo leggibile, mi aveva fatto capire che non avevo
capito nulla di C. io potrei riprendere e commentare parti di quello. (
http://ruby-it.org/pages/Roxi )

non riesco però più a rintracciare il codice… gabriele, se sei in ascolto
:slight_smile:

On 2/2/07, Giovanni I. [email protected] wrote:

letto buon codice ultimamente? che codice vi ha colpito?


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


– Kia

therubymine.com | be a miner

Grazie a tutti per la piacevole discussione,

Con il mio post non sono però riuscito ad imprimere al thread il taglio che
desideravo, ovvero la pragmaticità… con questo che voglio dire? Siamo
tutti appassionati di software e molti di leggono/hanno letto libri a
riguardo, se ci mettiamo a discutere su quanto siano
belli/brutti/importanti/inutili i pattern in questo/quel linguaggio
potremmo
andare avanti per anni, senza però condensare in codice e conoscenza. Prova
ne è il fatto che in 11 risposte al mio post non è presente una linea di
codice.

Riusciamo a portare qualche esempio pratico di utilizzo dei pattern?
Ovvero
riusciamo a dimostrare quando il pattern ha risolto un problema in un
dominio specifico?

Parto io per dare uno spunto anche se è banale:
A me il singleton ha reso possibile la definizione statica dei tabnav.

Quando fate un Tabnav fate:

class MyTabnav < Tabnav::Base
add_tab do
named ‘something’
links_to :controller => ‘fake’
end
end

add_tab è un metodo di classe definito Tabnav::Base ma quando lo chiamo
deve
aggiungere un tab in MyTabnav non in Tabnav::Base, quindi la list dei
tab
non deve essere un attributo di classe in Tabnav::Base altrimenti
verrebbe
condiviso tra tutti i tabnav dell’applicazione.

Io ho risolto con il singleton in questo modo:

require ‘singleton’
module Tabnav
class Base
include Singleton
attr_accessor :tabs

def self.add_tab &block
  raise "you should provide a block" if !block_given?
    instance.tabs ||= []
    instance.tabs << Tabnav::Tab.new(&block)
end

private

def initialize
  @tabs = []
end

end
end

In questo modo ogni classe che estende Tabnav::Base ha il suo singleton
e i
suoi tab. Chennesò, magari c’è un modo migliore di farlo… ma quello che
volevo ottenere è una discussione su roba ‘vera’.
Attendo ansiosamente riscontri (con codice, ovvio :-))

Paolo

On 2/2/07, chiaro scuro [email protected] wrote:

On 2/2/07, Giovanni I. [email protected] wrote:

letto buon codice ultimamente? che codice vi ha colpito?

On 2/2/07, david [email protected] wrote:

Verissimo. Non ci avevo mai pensato, ma è proprio così. Leggo
molto

therubymine.com | be a miner


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Paolo D.’
SeeSaw | Another point of view

[email protected]
personal http://paolodona.blogspot.com

Paolo Donà wrote:

Grazie a tutti per la piacevole discussione,

Attendo ansiosamente riscontri (con codice, ovvio :-))

Spiacente deluderti, ma continuo con la filosofia!

Una cosa che mi sembra importante da rimarcare e’ che in genere i
pattern non sono il modo piu’ semplice per fare una cosa, a volte puo’
essere cosi’, ma non e’ quello il punto, non nascono per quello. I
pattern servono a rendere il codice piu’ flessibile, quindi non ha tanto
senso dire “io ho risolto questo problema cosi’, con questo pattern”,
quanto “usando questo pattern ho risolto questo problema, e se cambia x,
y o z non devo riscrivere tutto”

Ciao

Chiaro Scuro wrote:

ma non trovi che molti pattern ‘classici’ evaporino in ruby? tanti di
quei
pattern ad esempio servono per aggirare i limiti di un linguaggio
statically
typed.

Beh, alcuni pattern potrebbero pure essere obsoleti, ma non certo
pensati per linguaggi statically typed: il libro contiene sia
implementazioni C++ che Smalltalk!

uL

"Paolo Donà " [email protected] writes:

Parto io per dare uno spunto anche se è banale:
A me il singleton ha reso possibile la definizione statica dei tabnav.

Forse é la stanchezza di venerdi’ sera ma non ho capito la differenza
tra usare un attributo di classe (comune a tutte le istanze di una
classe) ed usare attributi di instanza di una classe singleton (che da
sempre la stessa instanza).
Condividi sempre quell’attributo in tutta l’applicazione. Forse avevi
bisogno di condividere tutti gli attributi di una classe?

Ciao

— ugol [email protected] wrote:

Beh, alcuni pattern potrebbero pure essere obsoleti,
ma non certo
pensati per linguaggi statically typed: il libro
contiene sia
implementazioni C++ che Smalltalk!

-1, anche se lo dico dopo 5 bottiglie di vodka a
cracovia e giusto per spirito polemico…
I pattern imo non sono mai obsoleti, imho. ma va detto
che non sonoi sempre necessari.
Invito i lettori a cercare su internet “design pattern
in dynamic languages” di peter norvig (o qualcosa del
genere, google aiutera’).

In praTICA IL succo e’ che alcuni pattern sono
non-pattern in linguaggi di “livello superiore”,
qualsiasi cosa esso significhi. if-then-else in
assembly e’ un pattern, perche’ non e’ esprimibile con
le istruzioni della maggior parte delle cpu, ma e’
comunque uno schema che viene ripetuto spessissimo.
Ma in C o in qualsiasi linguaggio di alto livello,
non ha alcun senso parlare di “pattern per le
condizioni ternarie”, perchE’ esiste gia’ come parte
del linguaggio.

Ruby fino ad un certo punto permette di raggiungere
livelli di astrazione che trasformano un pattern in
una libreria (i.e. forwardable o singleton), e quindi
permettono di fattorizzare anche un qualcosa di
ripetitivo in una libreria, fatto che probabilmente
dice qualcosa a proposito dell’espressivita’ del
linguaggio.
Ovviamente lisp ed altri linguaggi permettono di
raggiungere livelli di astrazione anche piu’ alti
(giovanni, lo so che Smalltalk permette di raggiungere
questi livelli ma non lo dico perchE’ la mia
impressione e’ che generalmente non si faccia).

Ad ogni modo, la mia opionione e’ che i pattern non
siano mai inutili in assoluto, per la semplice ragione
che rappresentano stili di codice che sono stati visti
molte volte in azione (a differenza ad esempio del
“borg nonpattern” di alex martelli in python che
risolve gli stessi problemi del singleton ma e’ stato
creato a tavolino, e non estratto da ambienti di
produzione).
Al massimo alcuni pattern sono impliciti nel
linguaggio o nella libreria.

Just my two zloti.


icq: #69488917
blog it: http://riffraff.blogsome.com
blog en: http://www.riffraff.info


New Yahoo! Mail is the ultimate force in competitive emailing. Find out
more at the Yahoo! Mail Championships. Plus: play games and win prizes.
http://uk.rd.yahoo.com/evt=44106/*http://mail.yahoo.net/uk

On 2/2/07, Paolo Donà [email protected] wrote:

Riusciamo a portare qualche esempio pratico di utilizzo dei pattern? Ovvero
riusciamo a dimostrare quando il pattern ha risolto un problema in un
dominio specifico?

Mi sono trovato a mettere codice che gestisce comunicazioni di rete (o
altre comunicazioni asincrone) in una certa forma ricorrente. Una
forma ricorrente è un pattern, ma non so se questa abbia un nome…

Esempio: invio un comando all’altro lato della connessione, e quando
arriva la risposta reagisco in qualche modo (es. mostro un requester).
Il programma nel frattempo non deve congelarsi. Di solito si
avrebbero tutti i gestori di input remoto in un unico luogo, attivati
da un evento basato sulla categoria dell’input. A me servivano
gestori one-shot e serviva vederli in modo lineare. Pseudocodice:

sendCommand(
“foo”, proc { |answer|
display(answer)
})

E la definizione di sendCommand:

def sendCommand(command, reaction)
reactionWrapper = proc {
reaction()
networkLayer.unregisterHandler(‘on’ + command, reaction)
}

networkLayer.registerHandler('on' + command, reactionWrapper)
networkLayer.send(command)

end

My .02ptrn.


Massimiliano M.
code: http://dev.hyperstruct.net
blog: http://blog.hyperstruct.net

Il giorno ven, 02/02/2007 alle 20.51 +0000, gabriele renzi ha scritto:

typed.
che non sonoi sempre necessari.
Ma in C o in qualsiasi linguaggio di alto livello,
linguaggio.
Ovviamente lisp ed altri linguaggi permettono di
raggiungere livelli di astrazione anche piu’ alti
(giovanni, lo so che Smalltalk permette di raggiungere
questi livelli ma non lo dico perchE’ la mia
impressione e’ che generalmente non si faccia).

Generalmente no, perché il livello del linguaggio e della libreria è
sufficientemente elevato. Però quando serve lo si fa.

Ad ogni modo, la mia opionione e’ che i pattern non
siano mai inutili in assoluto, per la semplice ragione
che rappresentano stili di codice che sono stati visti
molte volte in azione (a differenza ad esempio del
“borg nonpattern” di alex martelli in python che
risolve gli stessi problemi del singleton ma e’ stato
creato a tavolino, e non estratto da ambienti di
produzione).
Al massimo alcuni pattern sono impliciti nel
linguaggio o nella libreria.

Più che altro certi pattern diventano talmente integrati nel linguaggio
o nella libreria che diventano degli standard: non più una soluzione tra
tante possibili, ma la soluzione.

Giovanni

Il giorno dom, 04/02/2007 alle 21.26 +0100, Antonio T. ha scritto:

Domanda: come fai il refactoring con ruby?
Si parlava in lista di komodo, ha un menù per il refactoring stile
eclipse?
L’argomento mi interessa molto. Diverse persone mi hanno sempre detto
a proposito dei dynamic language, ok son carini ma il refactoring?

In generale, la tipizzazione dinamica non è un problema (I tool
automatici per il refactoring sono apparsi prima in ambito Smalltalk -
con il refactoring browser - che in Java). Ci sono però altri problemi,
relativi al modo in cui il linguaggio è organizzato che rendono più
complicata la creazione di un tool automatico.

Questo non è comunque un problema così grosso come possa sembrare a
prima vista: la maggiore espressività di Ruby rispetto ad altri
linguaggi in genere rende gestibile applicare i refactoring a mano.

Giovanni