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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With