我有以下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
中完成一些特殊的魔法来调用三明治的所有方法(及其所有后代),例如call
而不是.fry!
作为.fry!({:ingredient=>special_ingredient})
。
已编辑:理想情况下,我们需要过滤内部块代码的调用,例如以下代码会引发任何prepare_with代码的异常,这不会过滤使用其他参数调用的方法:
=> Hamburger.prepare_with(bacon) do
=> Hamburger.fry!
=> h = Hash.new("Go fish")
=> Hamburger.add_mayo
=> end
答案 0 :(得分:3)
为什么fry!
和add_mayo
不是实例方法?
编辑:正如请求的问题海报,没有实例方法:
class Sandwich
class << self
def prepare_with(special_ingredient, &block)
@@default_opts = {:special_ingredient => special_ingredient}
block.call
end
def fry!(opts={})
opts = opts.merge(@@default_opts)
puts "fried with #{opts[:special_ingredient]}"
end
def add_mayo(opts = {})
puts "added mayo"
end
end
end
class Hamburger < Sandwich
end
Hamburger.prepare_with(:bacon) do
Hamburger.fry!
Hamburger.add_mayo
end
Hamburger.prepare_with(:tofu) do
Hamburger.fry!
end
输出:
fried with bacon
added mayo
fried with tofu
答案 1 :(得分:0)
简短回答
block.call :ingredient => special_ingredient
长答案
我认为你应该处理对象。 add_mayo和fry应该是实例方法而不是类方法。
我会看到像
这样的东西class Sandwich
class << self
def prepare &block
sandwich = self.new
block.call sandwich
sandwich
end
end
def fry(opts = {})
#stuff
end
def add_mayo(opts = {})
end
end
class Hamburger < Sandwich; end
hamburger = Hamburger.prepare do |h|
h.fry :ingredient => :bacon
h.add_mayo
end