Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用附加参数调用块中的所有方法_Ruby_Lambda_Metaprogramming - Fatal编程技术网

Ruby 使用附加参数调用块中的所有方法

Ruby 使用附加参数调用块中的所有方法,ruby,lambda,metaprogramming,Ruby,Lambda,Metaprogramming,我有以下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 a

我有以下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
简短回答

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
班级三明治
班级:培根
h、 加上蛋黄酱
结束

为什么
不炸
添加_mayo
be实例方法

编辑:根据问题海报的要求,不使用实例方法:

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

它们不可能是问题定义中的实例方法)好吧,你必须记住某个地方的特殊成分。在类变量中记住它们似乎很奇怪,但请稍候,我将更新我的答案以反映这一点。请看我编辑的笔记。谢谢。编辑了我的答案,让我知道这是否是你要找的。你的意思是哈希。new应该抛出一个错误吗?我不知道我是否真的理解你的编辑,但我认为这是第二个问题,这个问题不是很容易解决的。如果您试图在这里构建一个DSL,那么您可能应该坚持使用外部DSL。例如,您可以通过构建自己的解析器或使用treetop或racc来实现这一点。如果出现未知语句,则可以引发异常。@我必须开始等待更长时间,我的答案总是在底部。
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