【发布时间】:2010-09-10 16:18:11
【问题描述】:
我希望能够定义一个块,然后在动态生成的模块/类中评估该块。似乎我可以使用eval 和block.binding 以某种方式完成此操作,但我还没有弄清楚。
我以此为基础:
def define_module(name, &block)
name = name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
parts = name.split("::")
parts.each_with_index do |part, index|
sub_name = parts[0..index].join("::")
eval("module #{sub_name}; end")
end
clazz = eval(name)
clazz.class_eval(&block) if block_given?
clazz
end
def add_module(name, &block)
module_block = block
define_module(name).class_eval <<-EOF
def self.included(base)
base.class_eval do
# something like this, I'm stuck
instance_eval(&#{module_block})
end
end
EOF
end
我想这样使用它:
add_module("My::Library") do
def a_method
"added 'a_method'"
end
end
class ::User
include My::Library
end
user = ::User.new
assert_equal "added 'a_method'", user.a_method
有什么办法可以做这样的事情吗?
【问题讨论】:
-
好的,不要使用基于字符串的评估,使用基于块的评估,这样你就可以关闭
block
标签: ruby metaprogramming eval