是否可以从字符串(方法名称)和块(方法的内容)中定义ruby中的实例方法?
我想这需要使用instance_eval(),但我还没想出如何混合这两种数据类型。字符串和块都是动态确定的,所以它可以在开头创建带有“def#{string}”的块 - 我不知道该怎么做。
我的用例是一个代表Bacula配置文件的类。配置文件可以具有许多不同类型的资源。它们都存储在幕后相对复杂的数据结构中(出于其他原因,简化这种结构将无法实现我正在寻找的东西)。我希望通过命名方法快速访问资源。
例如,A代表一个配置文件,B代表另一个配置文件。 A有资源Director,Client,Job和B有Messages和Director。
在这种情况下,A应该有方法director(),client()和job(),而B有messages()和director()。其中每个都将从对象的相应配置文件中返回相关资源。
我知道有更简单的方法可以做到这一点(比如实现[]方法),但在这一点上,我正在寻求更好的解决方案以求好奇心。
答案 0 :(得分:4)
我认为您正在寻找的是模块上的方法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
[编辑(JörgWMittag):我修复了单例方法示例。]