Библиотека для временного изменения (основных) модулей Ruby - PullRequest
2 голосов
/ 27 декабря 2010

Я однажды натолкнулся на библиотеку Ruby (я не уверен, что она когда-либо была упакована как гем), которая позволяла вам удобно применять временные модификации к модулям Ruby.Эти изменения будут активны только в блоках, выполняемых в объявлении with, например:

with(modifications) do
  [interesting stuff requiring the modifications]
end

Это обеспечило отсутствие необходимости постоянно загрязнять (основные) модули только для того, чтобы сделать что-то особенное в определенныхмест.

В качестве конкретного примера того, что я хочу сделать: я хотел бы определить 'in?'метод Fixnum, поэтому пользователи внутреннего DSL могут набрать:

if value.in? [12, 16, 27, 28]
  [do something interesting]
end

Я бы обернул оценку DSL методом 'with', и мне не пришлось бы загрязнять Fixnum этим?метод.Я знаю, что это не так сложно сделать, но, возможно, есть некоторые темные углы, и у меня сложилось впечатление, что эта библиотека была очень удобной для этой цели.

Кто-нибудь знает название этой библиотеки, которую я ищу?Кажется, я помню, что это было что-то вроде «plusplus», но Google ничего мне не дает.

Ответы [ 3 ]

1 голос
/ 25 февраля 2011

Я наконец-то наткнулся на ответ: Переписать камень от raganwald .К сожалению, это было только доказательством концепции, и из этого мало что получилось.Он работает, разбирая Ruby в AST, искажая дерево и преобразовывая результат обратно в Ruby.Это, конечно, невероятно мощно, но Раганвальд так и не удосужился представить общие инструменты для реализации конкретных каландрирования, а создание нового, по его собственным словам, «мучительно».String будет означать поиск в AST определенного S-выражения, представляющего вызов in? для String, и преобразование этого в другой вызов метода;вероятно, in?(string, args) в локальном пространстве имен.Вскоре это превращается в проблему статической проверки типов, чтобы вы не интерпретировали каждый in? как String#in?.

1 голос
/ 27 декабря 2010

Хм .. это звучит как предложение о том, что может быть включено в Ruby 2. http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/

0 голосов
/ 27 декабря 2010

Существует множество подходов к замене метода (alias_method, включение модуля и т. Д.), Поэтому я предоставляю абстрактный код:

def with_modification   
   replace_method # for instance, alias_method

   yield    

   replace_method_back 
end

Это будет работать. Конечно, вы можете улучшить этот DSL, предоставив описание того, что именно вы хотите изменить, чтобы сделать этот метод гибким, это полностью ваше дело.

...