Aggiungere supporto readline a ruby

Posted by Dibi Store Sat, 24 May 2008 09:01:00 GMT

Readline è una libreria che vi permette di usare alcune interessanti funzioni da shell, come ^R per la reverse search oppure il supporto ai caratteri accentati. Sarebbe utile poter usare questo supporto anche all'interno di irb, tuttavia nella versione per mac osx non ci viene permesso. Tuttavia, questo articolo ci spiega come abilitare la libreria in meno di 5 minuti.

Posted in  | Tags  | no comments | no trackbacks

Finalmente Rails on Rubinius

Posted by Dibi Store Sun, 18 May 2008 09:32:00 GMT

E' notizia di ieri sera che rubinius è finalmente in grado di eseguire applicazioni rails. Entro la fine dell'anno, come detto da Fowler, saremo in grado di assistere al deploy di applicazioni commerciali su questa piattaforma.

Posted in  | Tags  | no comments | no trackbacks

Principi base di input/output (I/O) in ruby

Posted by Dibi Store Sat, 22 Mar 2008 18:01:00 GMT

Una domanda legittima che un programmatore può farsi nel corso dei suoi studi è: dov'è che esattamente viene rediretto l'output dei miei comandi?
Ad esempio in ruby, il metodo puts viene chiamato senza ricevente esplicito, quindi da qualche parte deve essere definito dove stampare la stringa.

Quando avviamo un programma in ruby, ci vengono fornite tre costanti, STDIN, STDOUT e STDERR, che indicano rispettivamente da dove prendere l'input, dove stampare l'output e infine gli errori. Queste variabili contengono degli indirizzi di memoria, possiamo verificarlo con un semplice inspect delle costanti.
A dire il vero, ruby ci mette a disposizione anche tre variabili globali ($stdin, $stdout e $stderr), che possono essere gestite direttamente da noi all'interno del programma per modifica il flusso I/O. Vediamo un esempio:

  file = File.new('foo', w)
  puts 'standard output'
  
  $stdout = file
  puts 'sto scrivendo all\'interno del file'
  
  $stdout = STDOUT
  puts 'sono nuovamente nel flusso standard'
  

Posted in  | Tags  | no comments | no trackbacks

Ruby inherited, come sapere quando viene create una sotto classe

Posted by Dibi Store Fri, 07 Mar 2008 16:20:00 GMT

A volte può essere utile conoscere quando viene creata una sotto classe di una particolare classe. Per questo può tornare utile il metodo di classe (scusate il gioco di parole) Class.inherited. Gli esempi seguenti sono auto esplicativi e non dovrebbero lasciare dubbi:


class Foo
  
  class << self  # => Uguale a def self.inherited...
    def inherited(sub_class)
      puts "Hai creato la sottoclasse #{sub_class}"
    end
  end

end

class Bar < Foo; end

Posted in  | Tags  | no comments | no trackbacks

Ruby define_method e module_eval: ancora sulla metaprogrammazione

Posted by Dibi Store Tue, 04 Mar 2008 10:28:00 GMT

Continuo la serie di articoli riguardo la metaprogrammazione in Ruby mostrando un paio di metodi molto utili. I metodi che seguono permettono di creare rispettivamente un metodo di istanza (ossia che disponibile successivamente aver istanziato la classe) e un metodo di classe (richimabile senza aver istanziato la classe). Questi metodi sono molto utilizzati ad esempio nel sorgente di rails e ci permettono di usare tutti quei metodi come validates_presence_of che ci vengono regalati in molte classi. Notate nel secondo esempio come usiamo in modo appropriato il codice class << self.

class Test; end
  
Test.module_eval do  
  define_method :talk do  
    puts "This is cool!"  
  end  
end  
  
Test.new.talk # => This is cool!


Test.module_eval do
  class << self
    define_method :talk_again do
      puts "This is more cool!"
    end
  end
end

Test.talk_again # => This is more cool!

Un applicazione reale? Immaginate di dover definire lo stesso metodo in dieci classi diverse contenute nell'array classi, potreste usare il codice seguente:

classi.each do |c|
  c.module_eval do
    define_method :validates... do |*args|
      ....
    end
  end
end

Notate che *args è un hash di argomenti che possono essere passati alla funzione, potete poi estrapolarli a vostro piacere. E' possibile anche dare un solo (o più) argomenti alla funzione con la seguente sintassi define_method :name do |arg1, arg2| ... end.

Risorse: documentazione modulo

Posted in  | Tags  | no comments | no trackbacks

Ruby Module::constants metaprogrammazione in Ruby

Posted by Dibi Store Mon, 03 Mar 2008 19:47:00 GMT

In ruby è possibile conoscere l'elenco delle costanti accessibili da un determinato modulo o classe attraverso il metodo Module::constants.
Il metodo ritorna un array delle costanti definite dal modulo e dai moduli che sono stati inclusi in essi. Di seguito degli esempi chiariranno meglio il concetto:

class Klass
  Foo = 'foo'
  
end

puts Klass.constants.include?('Foo')   # => true


module Foo
  Bar = 'bar'
end

puts Foo.constants.include?('Bar')   # => true


module Test
  include Foo
end

puts Test.constants.include?('Bar')   # => true

puts Object.constants.include?('Klass')   # => true

puts Object.constants.include?('Foo')   # => true

class Klass Foo = 'foo' end puts Klass::Foo # => foo Klass.const_set(:Test, 'valore') puts Klass::Test # => valore # Ridefiniamo la costante Foo Klass.const_set(:Foo, 'bar') puts Klass::Foo # => bar

Notate che l'ultimo test funziona, anche se giustamente viene restituito un warning che ci avvisa che la costante era già stata definita.

Per finire può essere utile ridefinire il metodo che viene invocato quando una costante non esiste, nell'esempio seguente restituirò un messaggio per avvertire che la costante non esiste:

def Object.const_missing(name)
  "La costante #{name} che cercavi non è ancora stata definita"
  
end

puts Class::Foo # => La costante Foo che cercavi non è ancora stata definita

Posted in  | Tags  | no comments | no trackbacks

Usare grep con ruby

Posted by Dibi Store Wed, 09 Jan 2008 10:29:00 GMT

Si, si può, il metodo fa parte del modulo enumerable, di seguito un esempio di utilizzo con rails:

  User.find(:first).attributes.keys.grep(/privacy/)
  => ["privacy", "third_parties_privacy"]

Figo no?

Posted in  | Tags  | no comments | no trackbacks

Stanchi di upto() e downto() ?

Posted by Dibi Store Wed, 26 Dec 2007 16:34:00 GMT

In effetti a volte vorremmo un metodo che si comportasse a prescindere se il primo parametro è maggiore o minore del secondo. Di cosa sto parlando?
In ruby possiamo iterare in un range di numeri con gli utilissimi metodi upto() e downto(). C'è un piccolo problema: come fare se no sappiamo a prescindere se il primo numero sarà più grande?


class Integer
  def to(limit,&blk)
    send(limit>self ? :upto : :downto, limit, &blk)
  end
end

Figo no? i crediti vanno a sepp2k nel canale irc di ruby-lang.

Posted in  | no comments | no trackbacks

Rak: il sostituto di grep, in Ruby!

Posted by Dibi Store Fri, 07 Dec 2007 18:42:00 GMT

Rak è una nuova gemma (scritta in ruby) che permette di effettuare alcune utili funzioni di ricerca. Molte volte è in grado di sostituire senza problemi il classico grep. Cio che più mi ha stupito usando rak, è l'utilità quando devo cercare dove viene ripetuta una data sringa di testo (o regular expression) all'interno di una directory. Infatti ipotizzano di trovarmi dentro la directory desiderata, mi basterà lanciare il comando rak 'my string' e automaticamente parsera i files restituendo un ricco output con sintassi colorata! Meglio di cosi!

Documentazione

Enjoy

Posted in  | Tags  | no comments | no trackbacks

Differenze di velocità tra Ruby 1.8 e Ruby 1.9

Posted by Dibi Store Fri, 07 Dec 2007 08:57:00 GMT

Visto chè tra un pò uscirà la nuova versione di ruby (la 1.9), ho pensato che sarebbe interessante pubblicare alcuni test che ho fatto per vedere la differenza di velocità nell' interpretazione tra le due versioni. Gli esperimenti sono stati fatti con pezzetti di codice usati comunemente, siete liberi di postare nei commenti anche i vostri esperimenti, che poi potranno essere integrati nel post.

####################
  def hash
    {"Key1" => "val1", "Key2" => "val2", :key3 => 'val3'}
  end

  def read_hash
    string = ""
    hash.each {|k,v| string << "#{k} is #{v}\n" }
  end
  
  ruby 1.8
        user     system      total        real
  first  9.720000   0.010000   9.730000 (  9.725511)
  
  ruby 1.9
        user     system      total        real
  first 11.190000   0.020000  11.210000 ( 11.198272)
####################
  def string_with_scan
    "Questo è un test semplice di scansione".scan(/./) { |x| x }
  end
  
  ruby 1.8
        user     system      total        real
  first  6.500000   0.010000   6.510000 (  6.505941)
  
  ruby 1.9
        user     system      total        real
  first  5.850000   0.010000   5.860000 (  5.868308)
####################
  def mega_sum
    ( 78 * 15 ) / 34 * 23 - (34 * 567)
  end
  
  ruby 1.8
        user     system      total        real
  first  0.910000   0.000000   0.910000 (  0.915802)
  
  ruby 1.9
        user     system      total        real
  first  0.310000   0.000000   0.310000 (  0.327869)
####################
  def with_tr
    "àòèùàòèùàòèàìììì".tr('àèìòù','aeiou')
  end
  
  ruby 1.8
        user     system      total        real
  first  1.580000   0.000000   1.580000 (  1.589578)
  
  ruby 1.9
        user     system      total        real
  first  1.810000   0.010000   1.820000 (  1.819424)

Considerazioni finali

Sicuramente questo post verrà aggiornato, magari integrando qualche regular expression come test, e altri metodi usati frequentemente

A mio parere ruby è migliorato molto per quanto riguarda la gestione dei numeri, i calcoli e family, ma ha perso qualcosina nelle operazioni con le stringhe, sperò che con la release definitiva prevista prima di natale ci sia qualche miglioramento in questo senso, ma comunque resta il fatto che sono stati fatti importantissimi miglioramenti che gioveranno di sicuro a questo fantastico linguaggio.

Posted in  | no comments | no trackbacks

Older posts: 1 2