Открытые классы в ruby, заметки для питонистов

от автора

По своему опыту знаю, что открытые классы в ruby раздражают и вызывают непонимание в среде питонистов. Ну в самом деле, что за странность открыть класс String и переопределить там size?

А можно рассмотреть вопрос в другой стороны, попробуем разобрать небольшой пример. Все знают как в 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *