Probabilmente ci sono due differenze principali:
Ruby ha chiusure eleganti e anonime.
Rails li usa con buoni risultati. Ecco un esempio:
class WeblogController < ActionController::Base
def index
@posts = Post.find :all
respond_to do |format|
format.html
format.xml { render :xml => @posts.to_xml }
format.rss { render :action => "feed.rxml" }
end
end
end
Le chiusure anonime / lambda semplificano l'emulazione di nuove funzionalità del linguaggio che richiedono blocchi. In Python, le chiusure esistono, ma devono essere denominate per poter essere utilizzate. Quindi, invece di essere in grado di utilizzare le chiusure per emulare nuove funzionalità del linguaggio, sei costretto a essere esplicito sul fatto che stai utilizzando una chiusura.
Ruby ha una metaprogrammazione più pulita e più facile da usare.
Questo è ampiamente utilizzato in Rails, principalmente per la sua facilità d'uso. Per essere precisi, in Ruby, puoi eseguire codice arbitrario nel contesto della classe. I seguenti snippet sono equivalenti:
class Foo
def self.make_hello_method
class_eval do
def hello
puts "HELLO"
end
end
end
end
class Bar < Foo # snippet 1
make_hello_method
end
class Bar < Foo; end # snippet 2
Bar.make_hello_method
In entrambi i casi, puoi quindi fare:
Bar.new.hello
che stamperà "CIAO". Il class_eval
metodo accetta anche una stringa, quindi è possibile creare metodi al volo, mentre viene creata una classe, con semantica diversa in base ai parametri passati.
In effetti, è possibile fare questo tipo di metaprogrammazione in Python (e anche in altri linguaggi), ma Ruby ha un vantaggio perché la metaprogrammazione non è uno stile di programmazione speciale. Deriva dal fatto che in Ruby tutto è un oggetto e tutte le righe di codice vengono eseguite direttamente. Di conseguenza, gli Class
es sono essi stessi oggetti, i corpi delle classi hanno un self
puntamento alla classe e puoi chiamare metodi sulla classe mentre ne crei uno.
Questo è in gran parte responsabile del grado di dichiaratività possibile in Rails e della facilità con cui siamo in grado di implementare nuove funzionalità dichiarative che sembrano parole chiave o nuove funzionalità del linguaggio a blocchi.