Методы экземпляра Ruby из строки и блока - PullRequest
3 голосов
/ 10 июля 2009

Можно ли определить метод экземпляра в ruby ​​из строки (имя метода) и блока (содержимое метода)?

Я предполагаю, что для этого нужно будет использовать instance_eval (), но я еще не выяснил, как смешать два типа данных. И строка, и блок определяются динамически, поэтому будет полезно создать блок с «def # {string}» в начале - я не знаю, как это сделать.

Мой вариант использования - это класс, представляющий файл конфигурации Bacula. Файл конфигурации может иметь много разных типов ресурсов. Все они хранятся в относительно сложной структуре данных за кулисами (по другим причинам упрощение этой структуры не даст того, что я ищу). Мне бы хотелось, чтобы ресурсы были быстро доступны через именованные методы.

Например, A представляет один файл конфигурации, B представляет другой. У A есть директор по ресурсам, Клиент, Работа, а у B есть Сообщения и Директор.

В этом случае у A должны быть методы Director (), client () и job (), а у B - messages () и Director (). Каждый из них возвращает соответствующий ресурс из соответствующего файла конфигурации объекта.

Я знаю, что есть более простые способы сделать это (например, реализовать метод []), но сейчас я стремлюсь к более сложному решению ради любопытства.

1 Ответ

4 голосов
/ 10 июля 2009

Я думаю, что вы ищете метод define_method в модуле; однако, это личное сообщение, поэтому вы должны использовать class_eval или что-то еще для его запуска.

body = proc { self * 3 }
name = "triple"
c = Numeric

c.class_eval { define_method(name.to_sym, &body) }

3.triple # 9

И метод с аргументами:

body = proc { |second| [self * 3, second * 3] }
name = "triple_both"
c = Numeric

c.class_eval { define_method(name.to_sym, &body) }

puts 3.triple_both(5) # [9, 15]

Чтобы поместить новый метод в одноэлементный объект (или Eigenclass, или как они там называются):

body = proc { puts @meme + @meme + @meme }
name = "meme"
class SwedishChef; def initialize; @meme = "bork"; end; end    
sc = SwedishChef.new
(class << sc; self; end).class_eval { 
  define_method(name.to_sym, &body)
}
sc.meme # borkborkbork

[EDIT (Jörg W Mittag): я исправил пример метода синглтона.]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...