metaprogramming/extend_with_several_modules_no_parens.rb

tests/_examples/metaprogramming/extend_with_several_modules_no_parens.rb in the metorex repository.

# extend takes several modules and puts the first one named nearest the
# object, and refuses anything that is not a module.
module Loud
  def speak = :loud
end

module Quiet
  def speak = :quiet
end

class Speaker
  extend Loud, Quiet
end

p Speaker.speak
p Speaker.singleton_class.ancestors.take 3
voice = Object.new
voice.extend Quiet, Loud
p voice.speak
[[1], [], [Speaker]].each do |given|
  Speaker.extend(*given)
rescue TypeError, ArgumentError => error
  p [error.class, error.message]
end

Output:

:loud
[#<Class:Speaker>, Loud, Quiet]
:quiet
[TypeError, "wrong argument type Integer (expected Module)"]
[ArgumentError, "wrong number of arguments (given 0, expected 1+)"]
[TypeError, "wrong argument type Class (expected Module)"]