$ cat /dev/random
ripley's miscellanous debris

2006/05 Archive

Net::Telnet ti da una mano

(2006-05-27)

Ruby e’ un ottimo linguaggio ad oggetti e come molti sapranno sta letteralmente spopolando nell’ambito delle web-application, mettendo in serie difficolta’ php (che paga ora la sua scarsa innovativita’, preferendo preservare lo status quo), java (e questo pochi se lo aspettavano) e python (che invece in ambito web e’ entrato di fresco), ma pochi ancora lo utilizzano in ambito di scripting di sistema.

Durante l’amministrazione di sistema si presentano spesso delle situazioni che richiedono l’esecuzione di azioni ad elevata meccanicita’.

Queste azioni meccaniche oltre ad essere molto noiose (scazzac…zi e’ il termine tecnico utilizzato da noi del settore :-)) e fonte di enormi perdite di tempo, sono soprattutto molto error prone.

La mente umana si sa e’ dotata di una innata fantasia ma e’ molto scarsa in tutti i lavori ripetitivi:

10 ripeti un milione di volte la stessa cosa 
20 per fare prima o poi qualche immane c..zata 
30 di cui ti pentirai nelle seguenti 12 ore... 
30 goto 10

Quindi abbiamo sufficienti scuse per cercare di scappottarci (termine tecnico che sta per riassegnare le risorse) anche questa ingrata mansione e sbolognarla alla nostra protesi al cervello (il termine tecnico usato per indicare il pc).

Divagazione Storica

Inizialmente gli amministratori di sistema automatizzavano tutto utilizzando le tante micro-utility di unix e lo shell scripting come collante.

Ma man mano che i compiti si fanno complessi (e quindi lo script piu’ lungo e articolato) gli script shell cominciano a diventare piuttosto difficili da comprendere e debuggare e si comincia il freeclimbing sugli specchi…

E cosi’ nasce perl… con il quale anche gli script piu’ piccoli risultano piuttosto difficili da comprendere e debbuggare :-PPPPP

A parte gli scherzi perl ha rappresentato un grosso passo avanti per quanto riguarda la complessita’ dei compiti che gli script di sistema sono in grado di compiere, con la sua straordinaria capacita’ di sintesi, ma questo purtroppo a discapito della leggibilita’ :-( ... ora il compito preferito da noi amministratori e’ capire cosa ca..o fanno questi script in perl che nemmeno Larry Wall riuscirebbe a leggere :-)))

Ruby da parte sua:

A mio avviso e’ un ottimo candidato per segnare una vera svolta per quanto riguarda la qualita’ del codice di questi script di sistema, e’ tutto potenziale che aspetta solo la carica per poter esplodere.

In ambito web la carica e’ stata Ruby On Rails, in questo ambito chissa’ :-)

Nel mentre siamo qui ad aspettare questa carica possiamo saggiarne un piccolo esempio concreto.

Scenario

Ho un piccolo router adsl (un USR 9105) che, anche se non evidenziato da nessuna parte sulla scatola, e’ equipaggiato con un kernel linux e un piccolo sistema composto da busybox, iptables, route etc. etc.

Il router puo’ essere configurato attraverso una comoda (quanto limitata) interfaccia web e attraverso un’interfaccia telnet.

Attraverso l’interfaccia telnet abbiamo a disposizione una shell busybox ristretta (non c’e’ ls ad esempio… ma c’e’ cat :-P) e un po’ di comandi tra cui oltre a quelli specifici dell’usr9105 abbiamo piu’ o meno ufficiosamente iptables :-)

Problema

L’interfaccia telnet e’ stata una manna perche’ mi permette di bypassare alcune limitazioni dell’interfaccia web (e non del router in se) come ad esempio la possibilita’ di NATting di una sola classe di indirizzi:

cioe' se uso 2 classi di indirizzi (ad esempio 192.168.0.x e 10.0.x.x) 
posso assegnare due ip al router (uno per classe) ma una sola potra' 
essere NATtata (quella dell'indirizzo primario)

CHE PALLE!!!

Per fortuna abbiamo l’interfaccia telnet e iptables!!!

Ci logghiamo via telnet, facciamo un bel:

iptables -t nat -A POSTROUTING --src 10.0.0.0/16 -j MASQUERADE

e abbiamo risolto.

Si… ma fino a quando non si riavvia il router!!!

CHE PALLEEEEE!!!

Non ci vuole molto a rendersi conto che in questo modo non stiamo facendo altro che caricarci un compito ingrato e ripetitivo (alla Lino Banfi operaio in fabbrica) che si presentera’ quando meno lo vorremo.

Soluzione

Armati di Ruby e Net::Telnet possiamo risolvere in 4 e 4 = 8 (righe di codice ;-)):

require 'net/telnet'

def test_172nat(usr9105)
  nat_table_buf = ""
  test_172nat_rx = /\n(MASQUERADE).*(10.0.0.0)/

  usr9105.cmd("iptables -t nat -L") { |c| nat_table_buf << c }

  if result = test_172nat_rx.match(nat_table_buf) then
    puts "OK: #{$1} #{$2}"
    return true
  else
    puts "KO"
    return false
  end
end

usr9105 = Net::Telnet::new("Host" => "10.0.0.1",
                               "Timeout" => 10,
                               "Prompt" => /[$%#>] \z/n)
usr9105.login("admin", "yourpassword") { |c| print c }

if not test_172nat(usr9105) then
   usr9105.cmd("iptables -t nat -A POSTROUTING --src 10.0.0.0/16 -j MASQUERADE")
   test_172nat(usr9105)
end

usr9105.close

Ovviamente questo e’ solo un piccolo snippet (imperfetto e senza un error handling serio), ma credo che renda l’idea.

Lo script e’ pienamente leggibile ma allo stesso tempo molto compatto, senza considerare il fatto che all’aumentare della complessita’ ci verranno in aiuto le caratteristiche di orientamento agli oggetti e meta-programmazione proprie di ruby (che sono inesistenti o primitive in perl)

Conclusione

Se siete amministratori di sistema imparate ruby e abbandonate perl al piu’ presto prima di bruciare nelle fiamme dell’inferno… ricordate

Dovete trovare ruby...
 prima che sia lui a trovare voi...

e se conoscete altri amministratori di sistema che scrivono script in perl raccontate anche a loro la parabola della povera Mildred :-)


Your Passion. Our Potential.

(2006-05-21)

Ogni volta che mi succede di imbattermi nella pubblicita’ della Microsoft “Your Potential. Our Passion” non posso fare a meno di rabbrividire.

Cosa avra' vvoooluuuto direee? :-)

Non ho mai letto o sentito nessuno commentare questa nuova campagna pubblicitaria dei nostri migliori amici.

Your Potential. Our Passion... uhm…

Sono veramente scarso come disegnatore ma spero che le immagini rendano + o – l’idea di cosa ne penso.

La loro passione? La tua potenzialita’... delimitata e inscatolata dai loro:

Tutti i loro diritti sono piu’ tutelati di qualsiasi liberta’ individuale.

E noi cosa possiamo fare? Quali armi abbiamo per difenderci?

Non abbiamo 
   ne' le loro risorse economiche 
   ne' i loro appoggi
   ne' la loro copertura legale  
   ne' i loro accordi commerciali 
   ne' la loro forza pubblicitaria.

Ma abbiamo qualcosa che a loro serve!

LA NOSTRA PASSIONE

Abbiamo solo bisogno di imparare:

ad usarla proficuamente (e non intendo solo nel suo senso monetario) 
e a non metterla al loro servizio (e non mi riferisco solo alla microsoft... 
ma alla classe vettoriale di cui fanno parte)

Il nostro motto? Your Passion. Our Potential.

Download svg source


Habemus Ruby ADesklets Binding

(2006-05-19)

Ruby e’ come la mortadella... fino fino fino che te se sciogglie in bbocca :-)

E’ stato piu’ semplice del previsto e gia’ ieri sera sono riuscito ad avere un prototipo che ben approssima un binding stabile delle adesklets.

Devo confessare che di grande aiuto mi e’ stato il neonato binding in perl a cui mi sono ispirato per la prima fase di prototipazione.

Il risultato e’ stato una libreria ruby molto “cammellosa”.

L’approccio del binding perl e’ fortemente procedurale… ma con ruby si puo’ fare di meglio che scrivere codice perl piu’ leggibile.

E cosi’ ho cercato di dargli un tocco piu’ ruby:

Analisi iniziale

Tutto e’ cominciato dalla necessita’ di studiare il funzionamento delle adesklets, e bisogna dire che il manuale e’ sufficientemente completo da darti un’idea abbastanza precisa del suo principio di funzionamento.

In particolare la sezione Extending adesklets spiega molto bene come un binding puo’ colloquiare con la sua istanza adesklets.

Tra i due binding attualmente presenti:

Prima prototipazione

Per prima cosa ho convertito la parte fondamentale del binding in perl (e cioe’ la componente che inizializza la comunicazione verso l’istanza adesklets) per testare di aver compreso bene il principio di funzionamento.

ADesklets e’ di fatto una console di comandi Imlib2 (Imlib2 sono delle librerie grafiche), come suggerisce il tutorial possiamo verificarlo di persona:

ripley@ubik:/home/ripley$ adesklets :
adesklets 0.6.1 (Thu May 18 09:45:13 CEST 2006), on Linux 2.6.12-10-386
[gcc 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)]
Press TAB for hints.
0 >>> window_resize 100 100
command 0 ok: window_resize 100 100
1 >>> window_show
command 1 ok: window_show
2 >>>

Soluzione simpatica non c’e’ che dire :-)

In pratica le nostre desklets dovranno fare altrettanto, e cioe’:

  1. avviare un’instanza adesklets
  2. inviare i comandi attraverso lo stdin (dell’istanza adesklets)
  3. ricevere le risposte attraverso lo stdout (come sopra :-)
  4. ricevere gli eventi attraverso lo stderr (idem :-P)

Il primo test (funzionante) che ho potuto fare e’ stato:

require 'adesklets'

ADesklets::open_streams

ADesklets::window_resize 100 100
ADesklets::window_show

sleep(10)

Bleahh!!! non sembra ruby… e’ veramente brutto come approccio :-)

Rubyficare prima dell’uso

Una desklets scritta come sopra non e’ molto ruby, come approccio e’ troppo poco orientato agli oggetti.

Allora ho dato un’occhiata al binding python ed effettivamente le desklets scritte in python (tutte al momento visto che il binding in perl e’ stato introdotto da poco e quello ruby esiste solo da ieri :-D):

import adesklets

class My_Events(adesklets.Events_handler):
    def __init__(self):
        adesklets.Events_handler.__init__(self)

    def __del__(self):
        adesklets.Events_handler.__del__(self)

    def ready(self):
        adesklets.window_resize(100,100)
        adesklets.window_reset(adesklets.WINDOW_MANAGED)
        adesklets.window_set_transparency(True)
        adesklets.window_show()

    def quit(self):
        print 'Quitting...'

    def alarm(self):
        print 'Alarm. Next in 10 seconds.'
        return 10

    def motion_notify(self, delayed, x, y):
        print 'Motion notify:', x, y, delayed

beh… al momento il mio binding in ruby permette di scrivere le desklets cosi’:

class Test1 < ADesklets::Base
  def ready(args)
        window_resize(100,100)
        window_show
  end

  def button_pressed(args)
        puts args
  end

  def motion_notify(args)
        puts args
  end   
end

Completare il binding

Il team che sviluppa adesklets ha pensato bene di scrivere un paio di script che esportano le costanti e i comandi adesklets dal codice sorgente (in C) in 2 file di testo nella directory scripting dei sorgenti (enums e prototypes).

Da questi 2 file i due binding esistenti generano le costanti e i metodi necessari ad interfacciarsi con adesklets.

Questa e’ stata una buona idea e ruby e’ molto amichevole nel parsing e generazione di file di testo e quindi ho scritto un piccolissimo script che genera’ una libreria ruby con le definizioni necessarie:

require 'erb'

TEMPLATE = ERB.new <<-EOT
### Autogenerated
module ADesklets
module AutoGenerated

  ## constants
<% @constants.each do |constant| %%>
  <%= constant.name %%> = <%= constant.value %%>
<% end %%>

## functions
<% @functions.each do |function| %%>
  ## <%= function.comment %%>
  def <%= function.name %%>(*args)
    $session.command("<%= function.name %%> \#{args.join(' ')}")
  end
<% end %%>

end
end
EOT

RConstant = Struct.new(:name, :value)
RFunction = Struct.new(:name, :comment)

@constants = Array.new
@functions = Array.new

open('../enums') do |f|
  f.each_line do |line|
    name, value = line.split
    @constants << RConstant.new(name, value)
  end
end

open('../prototypes') do |f|
  f.each_line do |line|
    comment = line
    name = line.split[0]
    @functions << RFunction.new(name, comment)
  end
end

puts TEMPLATE.result(binding)

Quasi quasi e’ stato troppo semplice :-)

E perche’ tutto sto pippotto? non potevi targzippare i sorgenti e basta?

Beh si li potevo e li targizzippero’ (anzi ho gia’ postato nella ml adesklets-dev e credo che non dovrebbero avere problemi ad integrarle nel pacchetto appena possibile) ma la cosa che piu’ conta e che questo dimostra che

un pincopallino qualunque da qualunque buco del c..o del mondo
puo' realizzare qualcosa che a qualcun'altro puo' servire o migliorare

Questo E’ il software libero!

tutti hanno una possibilita’:

quelli che sanno come fare e quelli
che non sanno ma hanno la voglia di imparare.

Se volete potete provare il binding da subito senza aspettare che lo finisca di stabilizzare (qualche modifichina ancora gliela voglio fare :-P) e che venga eventualmente integrato nella distribuzione ufficiale delle adesklets.

Download adesklets-ruby


Idee Malsane

(2006-05-18)

uhm… ... per lavoro mi sto studiando le adesklets , un framework per applet del desktop (o una imlib2 console come la definiscono loro ;-)

Devo dire che sono pensate molto bene… leggere e funzionali, scriptabili in python… ... uhm… scriptabili in python…
 e io non ho niente contro python... 
 chi mi conosce lo sa bene 
 (''ne l'aggiu fatti tanti'' (<------- ------->)
ma ultimamente scrivo molto in ruby perche’ mi diverte ed ho bisogno di fare pratica.

Allora perche’ non scriptare le adesklets in ruby?

non c'e' nessun impedimento, adesklets e' stato 
pensato per essere svincolato di fatto da python

L’unico impedimento e’ il binding :-)

Al momento (versione 0.6.1) esistono un binding python ed uno perl… ... uhm… uhm…


Rog 0.1.3 - nuovo fantastico logo

(2006-05-17)

Grazie a valvola ora rog ha un vero logo realizzato con mano assai piu’ abile della mia :-)

grazie valvola… ti aspetto come co-mantainer!!!


Rubycational Channel 1: Ruby e gli Oggetti

(2006-05-17)

Lo sapevate? In ruby tutto e’ un oggetto... sapevatelo su Rubycational Channel :-)

Questo significa che, ad esempio, per rovesciare una stringa faremo:

 puts "subbaqui".reverse
 puts "subbaqui".class
ed otterremo:
iuqabbus
String

Cosi’ facendo chiediamo a ruby di stampare il valore ritornato dai metodi class e reverse dell’oggetto “subbaqui” di tipo String.

Altri esempi?

  puts "subbaqui".upcase
  puts "subbaqui".size
SUBBAQUI
8

Non siete ancora convinti?

Beh allora sappiate che anche tutti gli altri tipi di dati seguono lo stesso principio, sia quelli implementati direttamente nell’interprete (e quindi scritti in C ) sia quelli defini in ruby nelle librerie.

Interi (FixedNum)

  puts 5.succ
  puts -1.abs
6
1

Array

  my_array = []
  my_array << 'primo'
  my_array.push 'secondo'
  puts my_array
primo
secondo

Successioni (Range)

  puts (1..5).min
  puts (1..5).max
  puts '[' + (1..5).to_a.join(',') + ']'
1
5
[1,2,3,4,5]

Espressioni Regolari (Regexp)

  prova = /bbaqui$/
  puts prova.source
  puts prova.match("subbaqui").pre_match
bbaqui$
su

Ora verificatelo di persona con irb:
ripley@ubik:~/projects/current/DevRandom/devrandom$ irb
irb(main):001:0> "unastringa".methods
=> ["%", "upto", "find_all", "[]=", "hex", "<<", "each", "sum", 
"object_id", "reverse!", "chop", "insert", "singleton_methods", 
"dump", "inject", "delete", "concat", "tr_s!", "equal?", "taint", 
"*", "succ", "sort_by", "frozen?", "instance_variable_get", "max", 
"strip!", "+", "kind_of?", "rjust", "respond_to?", "to_a", "index", 
"select", "slice", "oct", "type", "length", "chomp", 
"protected_methods", "squeeze", "upcase", "partition", "sub!", 
"delete!", "upcase!", "crypt", "to_sym", "grep", "eql?", 
"instance_variable_set", "lstrip!", "is_a?", "hash", "center", 
"send", "rindex", "between?", "reject", "to_s", "split", "class", 
"size", "strip", "tainted?", "private_methods", "succ!", "downcase", 
"gsub!", "count", "__send__", "downcase!", "intern", "member?", "squeeze!", 
"untaint", "find", "next", "each_with_index", "rstrip!", "each_line", "id", 
"sub", "slice!", "to_i", "<", "instance_eval", "method", "collect", "<=>", 
"inspect", "tr", "replace", "all?", "==", ">", "reverse", "===", "lstrip", 
"entries", "unpack", "clone", "public_methods", "chop!", "capitalize", 
"extend", "capitalize!", "scan", ">=", "freeze", "detect", "<=", "display", 
"each_byte", "zip", "__id__", "to_f", "casecmp", "gsub", "methods", "empty?", 
"to_str", "map", "=~", "tr_s", "any?", "tr!", "nil?", "dup", "match", "sort", 
"rstrip", "instance_variables", "next!", "swapcase", "min", "chomp!", 
"include?", "instance_of?", "swapcase!", "ljust", "[]"]
irb(main):002:0>


Rog alpha release 0.1.2

(2006-05-16)

Bene… dopo neanche 24 ore dall’upload dell’alpha release 0.1.0 di Rog ho gia’ dovuto uploadarne una versione 0.1.1 e 0.1.2 :-)

Dopo aver costretto alessandro (mods) a provare a gem-installare il pacchetto mediante il comando:

ripley@ubik:/home/ripley$ gem install rog -r

Abbiamo subito verificato che andava aggiunta una dipendenza al mio pacchetto in formato gem :

Mediante syntax potremo inserire in un post:

.#:code#ruby#
   def metodo1
     puts "hello" 
   end
.#:code#

per ottenere il seguente effetto nell’html generato:

  def metodo1
    puts "hello"
  end

bello, no? :-)

Ma de ce sta cuntamu?

Rog : un piccolo blog engine che anziche’ operare sul server (e quindi necessitare di uno spazio web con scripting), genera una serie di pagine html da uploadare su un normale web server (senza db o scripting) a partire da una serie di file di testo (formattati in textile) ed alcuni file ruby.

La domanda che sorge spontanea e’... era necessario?

beh necessario no… ma divertente si :-)

In pratica e’ un blogengine per geek e per morti di fame :-) senza spazio web dotato di db e scripting.

Magari puo’ essere uno stimolo per cominciare ad usare/imparare ruby :-) per me lo e’ stato :-P

E comu se usa?

Avete ragione… un getting started migliore potevo anche farlo :-)

Installazione

Prima di tutto dovete avere ruby... e’ importante! e’ importante! :-)

cercare di usare rog senza ruby ed erb
e' come cercare di avere la conoscenza senza la saggezza e il
senso del sacro!!! Immppazzisci e ti escono le bbolle dal naso!

Ue! e’ una citazione non sono pazzo!!! :-))))

Quindi… per non fare le bolle dal naso e’ necessario che vi procuriate ruby, erb e rubygems ... ma niente paura:

Se usate Debian o derivate vi bastera’ lanciare da linea di comando:

ripley@ubik:/home/ripley$ apt-get install ruby eruby

Altrimenti verificate la presenza di pacchetti simili per la vostra distribuzione. Nel peggiore dei casi potete scaricarvi i sorgenti e fare da voi:

Per rubygems scaricate tranquillamente i sorgenti e seguitene le istruzioni:

Installato rubygems vi risultera’ molto facile procurarvi rog come molte altre applicazioni ruby distribuite in questo modo.

RubyGems e' un sistema di pacchettizzazione per applicazioni e librerie
ruby, simile a CPAN di perl,
molto semplice e molto potente (sia per l'utente che per lo sviluppatore)

Ora siete pronti… e con un semplice:

ripley@ubik:/home/ripley$ gem install rog -r

Dovrebbe installarvi (chiedendovi conferma) rog e relative dipendenze.

Creare un nuovo blog

Per creare un nuovo blog userete il vostro nuovo comando rog:

ripley@ubik:/home/ripley$ rog create myblog
cp -r /usr/lib/ruby/gems/1.8/gems/rog-0.1.0/lib/rog/project myblog
ripley@ubik:/home/ripley$ cd myblog/
ripley@ubik:/home/ripley/myblog$ ls
README  Rakefile  blog
ripley@ubik:/home/ripley/myblog$
blog e’ la directory in cui si trovano:

Configurare il blog

Il file blog.yaml e’ il file di configurazione principale del blog, e il suo contenuto e’ abbastanza autoesplicativo:

blogurl: http://myblogurl/
publish_url: myuser@myblogurl:/home/myuser/public_html
blog_title: Im mio blog
blog_subtitle varie ed eventuali
pages:
 - About: about.html
 - Blog: index.html
buttons:
 - rog_powered.png: http://rog.rubyforge.org
 - ruby_powered.png: http://www.ruby-lang.it
 - emacs_powered.png: http://www.gnu.org/software/emacs
 - gnulinux_powered.png: http://www.gnu.org
projects:
 - your project: http://projecturl
links:
 - yourlink1: http://yourlink1url
 - yourlink2: http://yourlink2url
In particolare:

gli altri sono i nomi, le immagini e gli url corrispondenti ai link del menu’ e i bottoni powered.

Un altro file da modificare prima di iniziare il blogging e’ blog/pages/COMMON.rb:

@site_title = "titolo html del mio blog"

dove site_title rappresenta la stringe che appare nella barra del titolo del browser.

I blog, You blog

Ora potete cominciare a bloggare:

ripley@ubik:/home/ripley/myblog$ rake create_post
Post name: titolo_post
tags: miotag1 miotag2

In questo modo verranno creati 2 file in blog/pages/posts nel formato YYYYMMDD-nomepost.(rb|rhthml):

20060516-titolo_post.rb 20060516-titolo_post.thtml

nel primo (un file ruby di fatto) vengono impostati titolo e tag del post:

  #Set var for post title and tags
  @page_title = "prova123"
  @page_tags = ['prova','test','pippo']

nel secondo (formattato in textile) il testo del post:

inserire il test in textile qui

Creare gli archivi

Per auto-generare i file di archivio dei post potremo usare i task:

creare un tag-archivio si riduce a eseguire:

ripley@ubik:/home/ripley/myblog$ rake create_tag_archive
Tag name: mio_tag1

creare un month-archivio:

ripley@ubik:/home/ripley/myblog$ rake create_month_archive
Year: 2006
Month: 05

Generare l’output html del blog

Niente di piu’ semplice:

ripley@ubik:/home/ripley/myblog$ rake

Rimuove i vecchi html e li rigenera’. L’output finisce nella directory output, e puntandoci il nostro browser potremo gustare una preview del blog che andremo ad uploadare.

Upload del blog sul webserver

La directory output contiene l’intero blog e quindi e’ sufficiente upload-arla sul server in qualche modo.

Se sul server avete a disposizione un account ssh ed rsync dovrete semplicemente (dopo aver configurato correttamente la variabile publish_url nel file di configurazione blog.yaml) dare un:

ripley@ubik:/home/ripley/myblog$ rake publish
Password:

ed il gioco e’ fatto.

Ed ora?

Per avere altre informazioni sulle possibilita’ di rog potete leggerne il codice sorgente (ovviamente rilasciato secondo GPL) oppure approfondire rote su cui e’ basato la maggior parte dell’engine.

Tenete conto inoltre che ogni post puo’ contenere codice ruby, e che rote supporta la creazione i filtri e altre cose divertenti quindi se sapete usare ruby o avete intenzione di imparare potrete manipolarlo a vostro piacimento.

Buon divertimento, rpl


Ha le pinne... chi e'? e' subbaqqui!!!

(2006-05-15)

Chi e’? Cos’e’? :-)

E’ il mio personale /dev/random :-PPP

Il motivo per cui ho deciso di mettere online queste poche pagine html e’ semplice:

sempre piu' spesso ho trovato soluzioni ai problemi che si presentano
durante il lavoro e i miei esperimenti in blog personali di persone 
semplici come noi... jazzisti dell'informazione... 
risolvitori di problemi inesistenti... spingitori di seghe mentali

Quindi cerchero’ di mettere online brevi appunti di esperimenti in corso e quelli portati a termine, soluzioni a bug o malfunzionamenti, idee, progetti etc. etc.

Il blog stesso rappresenta un esperimento in corso: la realizzazione 
di un piccolo tool in ruby frutto dello studio di questa divertente 
tecnologia: Rog

Ruby

Ho incontrato ruby solo poco tempo fa… un giorno un mio amico mi disse:

nicola: Hai mai provato RubyOnRails?

uhm… no… a dire il vero non ho nemmeno mai provato ruby :-(

beh a posteriori direi: Male!!! dovevi provarlo :-)

E’ difficile descrivere la sensazione che si prova a scrivere codice ruby, anzi ancora prima ad imparare a scrivere codice ruby:

continuamente trovi qualche particolare 
  che ti stupisce... 
    eppure ti senti sempre piu' a casa :-)

Ruby.new

Come comincia l’avventura?

ripley@ubik:~$ irb

irb vi spalanchera’ immediatamente le porte di ruby!!!

print "hello, world!"


Full of CC licensed ripley's debris
HTML and CSS Design by Nicolas Fafchamps
Generated with Rote and Rog