Call all methods in a block with an additional parameter

I have the following Ruby classes:

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

I want to change the call to all methods of the class Hamburgerand add an extra key=>valueto the last Hash parameter.

In Sandwich.prepare_withit is necessary to perform special magic to invoke all Sandwich methods (and all its descendants), for example call, but simply .fry!how .fry!({:ingredient=>special_ingredient}).

EDITED : an additional point, ideally we need to filter out the call to the internal block code, for example, the following code can throw an exception for any prepare_with code that does not handle the methods that call it with an additional parameter:

=> Hamburger.prepare_with(bacon) do
=>   Hamburger.fry!
=>   h = Hash.new("Go fish") 
=>   Hamburger.add_mayo
=> end
+3
source share
2 answers

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
+3

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
0

All Articles