Monday, November 2, 2009

Ruby initialize puzzle (more exercises)

(continued from phosphorescence: Ruby initialize puzzle (answer part))

If you want to call both initialize methods, you should write initialize method of Bar module like below:
module Bar
  def initialize(b)
    super
    puts "#{b} World"
  end
end

irb(main):018:0> Sample.new('qux')
Hello qux
qux World
=> #<Sample:0x256e918>

In this case, argument numbers of each initialize method are same. But if argument numbers of each initialize method are not same, you should not omit parentheses and arguments of super method: i.e., you should write parentheses and arguments of super method.
class Hoge
  def initialize
    puts "Hello World"
  end
end
module FooBar1
  def initialize(a)
    super()
    puts "Hello #{a}"
  end
end
module FooBar2
  def initialize(b, c)
    super(b)
    puts "#{c} World"
  end
end
class Sample < Hoge
  include FooBar1
  include FooBar2
  def initialize(d)
    super(d, d)
  end
end

irb(main):028:0> Sample.new('qux')
Hello World
Hello qux
qux World
=> #<Sample:0x2553820>
But above case, it's sensitive to order of including module. For example, if FooBar2 is included before FooBar1,
class Sample < Hoge
  include FooBar2
  include FooBar1
  def initialize(d)
    super(d)
  end
end

error occurs like below:
irb(main):028:0> Sample.new('qux')
ArgumentError: wrong number of arguments (0 for 2)
        from (irb):9:in `initialize'
        from (irb):25:in `initialize'
        from (irb):28:in `new'
        from (irb):28
        from /opt/ruby-1.9.1/bin/irb:12:in `<main>'

No comments:

Post a Comment