Ймовірно, є дві основні відмінності:
Ruby має елегантні, анонімні закриття.
Rails ефективно використовує їх. Ось приклад:
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
Анонімні закриття / лямбди полегшують наслідування нових мовних функцій, які забирають блоки. У Python існують закриття, але вони повинні бути названі для використання. Отже, замість того, щоб мати змогу використовувати закриття для емуляції нових мовних функцій, ви змушені бути явними щодо того, що використовуєте закриття.
Ruby має чистіший, простіший у використанні метапрограмування.
Це широко використовується в Rails, в першу чергу через те, наскільки простий у використанні. Якщо бути конкретним, у Ruby ви можете виконати довільний код у контексті класу. Наступні фрагменти еквівалентні:
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
В обох випадках ви можете зробити наступне:
Bar.new.hello
який надрукує "ПРИВІТАЙ". class_eval
Метод також приймає рядок, так що можна створювати методи на льоту, як створюється клас, що мають різну семантику на основі параметрів, які передаються в.
Насправді це можливо зробити подібного роду метапрограмування на Python (та й інших мовах теж), але Ruby має ногу, оскільки метапрограмування не є особливим стилем програмування. Це випливає з того, що в Ruby все є об'єктом і всі рядки коду виконуються безпосередньо. Як результат, Class
es - це самі об'єкти, тіла класу мають self
вказівку на Клас, і Ви можете викликати методи класу під час його створення.
Це значною мірою відповідає за ступінь декларативності, можливої в Rails, і легкість, за допомогою якої ми можемо впроваджувати нові декларативні функції, схожі на ключові слова або нові функції блочної мови.