【发布时间】:2023-03-06 17:55:01
【问题描述】:
我有以下 Ruby 类:
class Sandwich
class << self
def prepare_with(special_ingredient, &block)
# Some very very special magic is done here to
# call instead just .fry! as .fry!({:ingredient=>special_ingredient})
# and for any other method the same
end
def fry!(opts= {})
end
def add_mayo(opts = {})
end
end
end
class Hamburger < Sandwich
end
=> Hamburger.prepare_with(bacon) do
=> Hamburger.fry!
=> Hamburger.add_mayo
=> end
我想修改调用Hamburger类的所有方法,并在最后一个参数Hash中添加额外的key=>value。
应该在 Sandwich.prepare_with 中执行一些特殊的魔法来调用 Sandwich(及其所有后代)的所有方法,例如 call 而不是将 .fry! 调用为 .fry!({:ingredient=>special_ingredient})。
已编辑:理想情况下我们需要过滤内部块代码的调用的附加点,例如以下代码会引发任何 prepare_with 代码的异常,它不会过滤它使用附加参数调用的方法:
=> Hamburger.prepare_with(bacon) do
=> Hamburger.fry!
=> h = Hash.new("Go fish")
=> Hamburger.add_mayo
=> end
【问题讨论】:
-
编辑了我的答案,如果这是您要找的,请告诉我
-
你的意思是 Hash.new 应该抛出错误吗?
-
我不知道我是否真的理解你的编辑,但我认为这是第二个问题,这个问题解决起来并不容易。如果您尝试在这里构建 DSL,您可能应该坚持使用外部 DSL。例如,您可以通过构建自己的解析器或使用 treetop 或 racc 来实现这一点。然后,如果出现未知语句,您可以引发异常。
标签: ruby lambda metaprogramming