只是为了好玩 - 通过块向对象添加方法
再次只是为了好玩,但是是否有可能以某种方式获取包含方法定义的块并将它们添加到对象中?以下内容不起作用(我从没想过它会起作用),但只是为了让您了解我正在玩什么。
我确实知道我可以使用 class << 重新打开一个类existing_object
并以这种方式添加方法,但是代码有没有办法在块中传递该信息?
我想我想在这里借用一点Java 的思维。
def new(cls)
obj = cls.new
class << obj
yield
end
obj
end
class Cat
def meow
puts "Meow"
end
end
cat = new(Cat) {
def purr
puts "Prrrr..."
end
}
cat.meow
# => Meow
# Not working
cat.purr
# => Prrrr...
编辑 |这是上述内容的工作版本,基于 Edgerunner 的答案:
def new(cls, &block)
obj = cls.new
obj.instance_eval(&block)
obj
end
class Cat
def meow
puts "Meow"
end
end
cat = new(Cat) {
def purr
puts "Prrrr..."
end
}
cat.meow
# => Meow
cat.purr
# => Prrrr...
Just for fun, again, but is it possible to take a block that contains method definitions and add those to an object, somehow? The following doesn't work (I never expected it to), but just so you get the idea of what I'm playing around with.
I do know that I can reopen a class with class << existing_object
and add methods that way, but is there a way for code to pass that information in a block?
I guess I'm trying to borrow a little Java thinking here.
def new(cls)
obj = cls.new
class << obj
yield
end
obj
end
class Cat
def meow
puts "Meow"
end
end
cat = new(Cat) {
def purr
puts "Prrrr..."
end
}
cat.meow
# => Meow
# Not working
cat.purr
# => Prrrr...
EDIT | Here's the working version of the above, based on edgerunner's answer:
def new(cls, &block)
obj = cls.new
obj.instance_eval(&block)
obj
end
class Cat
def meow
puts "Meow"
end
end
cat = new(Cat) {
def purr
puts "Prrrr..."
end
}
cat.meow
# => Meow
cat.purr
# => Prrrr...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用
class_eval
(也可以别名为module_eval
) 或 < code>instance_eval 分别评估类/模块或对象实例上下文中的块。You can use
class_eval
(also aliased asmodule_eval
) orinstance_eval
to evaluate a block in the context of a class/module or an object instance respectively.是的,
我怀疑您想到了这一点,并且正在寻找一些其他方式,但以防万一......
根据记录,这不是动态添加方法的常用方式。通常,动态方法以块本身的形式开始生命,例如,请参见 *模块#define_method*。
Yes
I suspect you thought of this and were looking for some other way, but just in case...
For the record, this isn't the usual way to dynamically add a method. Typically, a dynamic method starts life as a block itself, see, for example, *Module#define_method*.