2013-07-19 5 views
0

Я хотел бы использовать некоторые удобные методы использования; в частности Enumerable#to_a, на объектах, которые удовлетворяют контракту Enumerable (то есть реализуют each), но которые не включают Enumerable.Вызов метода mixin на объекте, который не включает этот mixin

Я понял, что это похоже на работу:

Enumerable.instance_method(:to_a).bind(obj).call 

Но это, кажется, действительно многословным и не-Rubyesque. Есть ли лучший/более чистый/быстрый способ сделать это? Я бы предпочел не изменять основной объект, чтобы избежать непреднамеренных последствий.

По сути, я ищу javascript's apply или call.

Редактировать: Мотивация для этого - это, по сути, инкапсуляция: я хотел бы сделать это с объектами в классах, которые я не писал, не контролирую, на самом деле не нужно разбираться в глубине и может плохо реагируют на возможность заменить свои собственные методы общей реализацией. Я понимаю, что просто включение Enumerable будет работать в большинстве случаев, но когда это пойдет не так, это может быть больно отлаживать, поэтому, если есть простой способ получить преимущества микширования, не будучи настолько инвазивным, я бы предпочел это.

+2

Почему вы не принимая во внимание только включить перечислимых? Что с этим не так? –

+0

Класс является частью библиотеки, которую я не контролирую, и, как правило, я бы хотел свести к минимуму беспорядок со своими внутренностями. В принципе, для меня нет причин перезаписывать любые существующие методы в классе и, возможно, затрагивать других пользователей этого класса. Я имею в виду, это не очень вероятно; но зачем рисковать непонятными ошибками, если есть какой-то другой способ? –

ответ

1

Похоже, что по какой-либо причине вы не хотите изменять определение класса до include Enumerable, но вы также можете, конечно, просто расширить конкретные экземпляры.

Итак, вы указали, что obj реализует each так что вы можете сделать это:

obj.extend(Enumerable).to_a 

Ах, от вашего первоначального вопроса, я думал, что цель состояла в том, чтобы просто не изменить класс, поэтому расширение экземпляр был наиболее логичное решение. Однако, похоже, вы не хотите изменять класс или какой-либо экземпляр.

Я хотел бы сделать следующее тогда:

obj.to_enum.to_a 
+0

Это позволяет избежать расширения всех экземпляров объекта, но все равно нарушает инкапсуляцию объектов: OK; но не идеально. Кроме того, это, вероятно, будет довольно медленным решением, если я сделаю это повсюду. –

Смежные вопросы