是否可以通过字符串(方法名称)和 block (方法的内容)在 ruby 中定义实例方法?
我想这将需要使用 instance_eval(),但我还没有想出如何混合这两种数据类型。字符串和 block 都是动态确定的,因此可以在开头使用“def#{string}”创建 block - 我不知道该怎么做。
我的用例是一个代表 Bacula 配置文件的类。配置文件可以有许多不同类型的资源。它们都存储在幕后相对复杂的数据结构中(由于其他原因,简化这种结构将无法实现我正在寻找的东西)。我希望可以通过命名方法快速访问资源。
例如,A代表一个配置文件,B代表另一个。 A 有资源 Director、Client、Job,B 有 Messages 和 Director。
在这种情况下,A 应该有方法 director()、client() 和 job(),而 B 有 messages() 和 director()。这些中的每一个都会从对象各自的配置文件中返回相关资源。
我知道有更简单的方法可以做到这一点(比如实现 [] 方法),但出于好奇,目前我正在寻求更难的解决方案。
最佳答案
我认为您正在寻找的是 Module 上的方法 define_method
;但是,它是私有(private)的,因此您必须使用 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örg W Mittag):我修复了单例方法示例。]
关于来自字符串和 block 的 Ruby 实例方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1110388/