Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call all methods in block with additional parameter

I`ve got 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 modify of calling all methods of Hamburger class and add additional key=>value into last parameter Hash.

Some special magic should be done in Sandwich.prepare_with to call all methods of Sandwich (and all its descendants), like call instead just .fry! as .fry!({:ingredient=>special_ingredient}).

EDITED: Additional point that ideally we need to filter calling of inside block code, for example following code would raise exception for any prepare_with code, that doesn`t filter methods it calling with additional parameter:

=> Hamburger.prepare_with(bacon) do
=>   Hamburger.fry!
=>   h = Hash.new("Go fish") 
=>   Hamburger.add_mayo
=> end
like image 522
Sergey Avatar asked Jun 17 '26 02:06

Sergey


1 Answers

Why wouldn't fry! and add_mayo be instance methods?

EDIT: as the question poster requested, without instance methods:

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

output:

fried with bacon
added mayo
fried with tofu
like image 173
Patrick Oscity Avatar answered Jun 19 '26 15:06

Patrick Oscity



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!