А можно рассмотреть вопрос в другой стороны, попробуем разобрать небольшой пример. Все знают как в python разные типы проверяются на истинность — всё что пусто, то ложь. В ruby это не так, здесь ложь это nil и false. Иногда было бы удобнее как в python.
Как это можно решить например в rust, включая поддержку для встроенных типов:
trait Existable { fn exist(&self) -> bool; } impl Existable for int { fn exist(&self) -> bool { if *self == 0 { false } else { true } } } fn main () { assert!(5.exist() == true) assert!(0.exist() == false) }
Представим что в python схема не такая, и мы хотим ее реализовать. В python нельзя определить новые методы для сторонних классов, поэтому можно сделать что-то вроде:
class Trait(object): def __init__(self): self.registry = {} def impl(self, typ): def reg(func): self.registry[typ] = func return func return reg def __call__(self, arg): return self.registry[arg.__class__](arg) Existable = Trait() @Existable.impl(int) def int_exists(i): return False if i == 0 else True if __name__ == '__main__': assert Existable(0) == False assert Existable(5) == True
Ну или использовать какую-нибудь библиотеку, которая толковее минутного наброска.
Как в ruby реализовали подобную штуку?
class Object # File activesupport/lib/active_support/core_ext/object/blank.rb, line 13 def blank? respond_to?(:empty?) ? empty? : !self end end
Метод `empty?` определен на классах `Array` и `Hash` (как минимум). Определите на своем классе и метод `blank?` будет корректно работать. То есть здесь мы имеем trait в ruby — объекты отвечающие на `empty?` реализуют trait проверки на пустоту, тот самый `Existable`.
Это простейший корректный пример использования открытых классов в ruby, а есть и много других замечательных штук из ActiveSupport, одной из частей Ruby on Rails.
Надеюсь благодаря такому простому примеру, вы теперь понимаете, что открытые классы в ruby вовсе не зло, а полезный инструмент, который в прямых руках позволяет реализовывать расширения среды изящно.
Если было не совсем понятно, что я имею в виду — открытые классы в ruby позволяют доопределять поведение любых, встроенных в том числе, классов, также как и traits в rust и других языках.
ссылка на оригинал статьи http://habrahabr.ru/post/214191/
Добавить комментарий