У Рубі є блоки; Пітон ні.
Python має функції; Рубі ні. У Python ви можете взяти будь-яку функцію чи метод і передати її іншій функції. У Ruby все є методом, і методи неможливо передати безпосередньо. Натомість вам потрібно загортати їх у програму Proc, щоб передавати їх.
Ruby та Python підтримують закриття, але різними способами. У Python ви можете визначити функцію всередині іншої функції. Внутрішня функція має доступ до читання до змінних із зовнішньої функції, але не записує доступ. У Ruby ви визначаєте закриття за допомогою блоків. Закриття мають повний доступ для читання і запису до змінних із зовнішньої області.
У Python є спільні розуміння, які досить виразні. Наприклад, якщо у вас є список номерів, ви можете написати
[x*x for x in values if x > 15]
щоб отримати новий перелік квадратів усіх значень більше 15. У Ruby вам потрібно буде написати наступне:
values.select {|v| v > 15}.map {|v| v * v}
Код Ruby не здається таким компактним. Він також не настільки ефективний, оскільки спочатку перетворює масив значень у коротший проміжний масив, що містить значення більше 15. Потім він приймає проміжний масив та формує остаточний масив, що містить квадрати проміжних. Потім проміжний масив викидається. Отже, Рубі закінчує 3 масиви пам'яті під час обчислення; Python потребує лише списку вводу та списку, що виходить.
Python також забезпечує подібні розуміння карт.
Python підтримує кортежі; Рубі ні. У Ruby ви повинні використовувати масиви для імітації кортежів.
Ruby підтримує вимикачі / випадок випадку; Пітон ні.
Ruby підтримує стандартного expr ? val1 : val2
потрійного оператора; Пітон ні.
Ruby підтримує лише одиночне успадкування. Якщо вам потрібно імітувати кілька успадкованих даних, ви можете визначити модулі та використовувати суміші, щоб перетягнути методи модулів у класи. Python підтримує багатократне успадкування, а не змішування модулів.
Python підтримує лише однолінійні лямбда-функції. Рубінові блоки, які є ламбда-функціями, можуть бути довільно великими. Через це код Ruby зазвичай пишеться у більш функціональному стилі, ніж код Python. Наприклад, щоб перейти до списку в Ruby, ви зазвичай робите
collection.each do |value|
...
end
Блок працює дуже схоже на функцію, яка передається collection.each
. Якби ви робили те ж саме в Python, вам слід було б визначити іменовану внутрішню функцію, а потім передати її колекції кожному методу (якщо список підтримує цей метод):
def some_operation(value):
...
collection.each(some_operation)
Це не дуже добре тече. Отже, зазвичай в Python використовується наступний нефункціональний підхід:
for value in collection:
...
Використання ресурсів у безпечний спосіб сильно відрізняється між двома мовами. Тут проблема полягає в тому, що ви хочете виділити якийсь ресурс (відкрити файл, отримати курсор бази даних тощо), виконати якусь довільну операцію над ним, а потім закрити її безпечним способом, навіть якщо трапляється виняток.
У Ruby, оскільки блоки настільки прості у використанні (див. № 9), ти зазвичай кодуєш цей шаблон як метод, який бере блок для довільної операції, що виконується на ресурсі.
У Python передача функції для довільної дії є дещо незграбною, оскільки вам потрібно написати внутрішню функцію (назва №9). Натомість Python використовує with
оператор для безпечної роботи з ресурсами. Див. Як правильно очистити об’єкт Python? для отримання детальної інформації.