Страницы

Поиск по вопросам

суббота, 13 июля 2019 г.

Конструктор динамических имён методов

У меня есть несколько методов с однотипными префиксами.
def get_foo # code end
def get_bar # code end
Я хочу научиться генерировать эти префиксы автоматически (по аналогии с тем, как это сделано в Rails: Model.find_by_smth).
Т.е. я хочу создать некий scope get_, в который можно поместить метод foo и тот автоматически приобретёт префикс get_ и станет доступен как get_foo
Как это можно реализовать?

Пример желаемого синтаксиса.
module Bar # некая обётка `get_` end
class Foo include Bar
<некая обёртка из Bar> do def foo puts 'У меня есть мысль, и я её думаю!' end
def bar puts 'А можно я её тоже немножечко подумаю?' end end end
foo = Foo.new
foo.get_foo # => "У меня есть мысль, и я её думаю!" foo.get_bar # => "А можно я её тоже немножечко подумаю?"


Ответ

class Module def with_prefix(prefix, &block) m = Module.new m.instance_eval(&block) m.methods(false).each do |name| define_method "#{prefix}_#{name}", &m.method(name) module_function "#{prefix}_#{name}" unless self.is_a?(Class) end end end
class Foo with_prefix :get do with_prefix :and do def foo puts "У меня есть мысль, и я её думаю!" end
def bar puts "А можно я её тоже немножечко подумаю?" end end end end
foo = Foo.new
foo.get_and_foo # => "У меня есть мысль, и я её думаю!" foo.get_and_bar # => "А можно я её тоже немножечко подумаю?"
Что делает этот код?
Объявляет метод with_prefix в суперклассе всех классов Метод принимает имя префикса и блок кода Выполняет блок в контексте анонимной функции Это позволяет исполнять оператор def в анонимном модуле, а не в классе Перебирает все методы внутри модуля Создаёт методы с префиксами для каждого метода

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

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