...

пятница, 28 февраля 2014 г.

Открытые классы в 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 и других языках.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий