Provavelmente, existem duas diferenças principais:
Ruby tem encerramentos elegantes e anônimos.
Rails os usa com bons resultados. Aqui está um exemplo:
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
Fechamentos / lambdas anônimos tornam mais fácil emular novos recursos de linguagem que receberiam blocos. Em Python, os encerramentos existem, mas devem ser nomeados para serem usados. Portanto, em vez de poder usar closures para emular novos recursos de linguagem, você é forçado a ser explícito sobre o fato de que está usando uma closure.
Ruby tem uma metaprogramação mais limpa e fácil de usar.
Isso é usado extensivamente no Rails, principalmente por causa de sua facilidade de uso. Para ser específico, em Ruby, você pode executar código arbitrário no contexto da classe. Os seguintes snippets são equivalentes:
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
Em ambos os casos, você pode fazer:
Bar.new.hello
que imprimirá "OLÁ". O class_eval
método também recebe uma String, portanto, é possível criar métodos dinamicamente, conforme uma classe está sendo criada, que possuem semânticas diferentes com base nos parâmetros que são passados.
É, de fato, possível fazer esse tipo de metaprogramação em Python (e outras linguagens também), mas Ruby tem uma vantagem porque a metaprogramação não é um estilo especial de programação. Isso decorre do fato de que em Ruby, tudo é um objeto e todas as linhas de código são executadas diretamente. Como resultado, Class
es são eles próprios objetos, corpos de classe têm um self
apontador para a classe e você pode chamar métodos na classe enquanto está criando um.
Isso é em grande parte responsável pelo grau de declaratividade possível no Rails, e pela facilidade com que somos capazes de implementar novos recursos declarativos que parecem palavras-chave ou novos recursos de linguagem de bloco.