Newbie problem: ArgumentError when creating subclass

Could someone explain why the following code raises ArgumentError. Thanks.

class SuperClass
  
  def initialize #Make sure you spell 'initialize' correctly!
    @my_attr = 1
  end
  
  attr_reader :my_attr
end

class SubClass < SuperClass

  def initialize(data1, data2)
    super
    @data1 = data1
    @data2 = data2
  end
  
  attr_reader :data1
  attr_reader :data2
  
end

test = SubClass.new("one", "two")
puts test.my_attr
puts test.data1
puts test.data2

$ ruby inheritance_problem.rb
inheritance_problem.rb:13:in `initialize': wrong number of arguments
(2 for 0) (ArgumentError)
        from inheritance_problem.rb:13:in `initialize'
        from inheritance_problem.rb:23:in `new'
        from inheritance_problem.rb:23

This should be super(). Without the parenthesis it defaults to passing
the arguments given to the current method to the super class's
implementation.

Ryan

···

On 4/2/07, Dan Stevens (IAmAI) <dan.stevens.iamai@gmail.com> wrote:

Could someone explain why the following code raises ArgumentError. Thanks.

class SuperClass

        def initialize #Make sure you spell 'initialize' correctly!
                @my_attr = 1
        end

        attr_reader :my_attr
end

class SubClass < SuperClass

        def initialize(data1, data2)
                super

Alle lunedì 2 aprile 2007, Dan Stevens (IAmAI) ha scritto:

Could someone explain why the following code raises ArgumentError. Thanks.

class SuperClass

  def initialize #Make sure you spell 'initialize' correctly!
    @my_attr = 1
  end

  attr_reader :my_attr
end

class SubClass < SuperClass

  def initialize(data1, data2)
    super
    @data1 = data1
    @data2 = data2
  end

  attr_reader :data1
  attr_reader :data2

end

test = SubClass.new("one", "two")
puts test.my_attr
puts test.data1
puts test.data2

$ ruby inheritance_problem.rb
inheritance_problem.rb:13:in `initialize': wrong number of arguments
(2 for 0) (ArgumentError)
        from inheritance_problem.rb:13:in `initialize'
        from inheritance_problem.rb:23:in `new'
        from inheritance_problem.rb:23

If you call super with no arguments, it will pass to the superclass method all
the parameters given to the sublcass method. In your case,
SubClass#initialize takes 2 arguments, while SuperClass#initialize takes no
arguments. Since you call super without arguments, ruby passes both arguments
to SuperClass#initialize, then complains because the number of arguments is
wrong. What you need to do is:

class SubClass < SuperClass
  def initialize(data1, data2)
    super()
    ...
  end
  ...
end
  
If SuperClass#initialized required one argument, you'd do:

def initialize(data1, data2)
   super(data1)
   ...

By the way, you can pass more than one argument to attr_reader, so you can
write

attr_reader :data1, :data2

I hope this helps

Stefano

Hi,

···

Am Dienstag, 03. Apr 2007, 05:59:31 +0900 schrieb Ryan Leavengood:

On 4/2/07, Dan Stevens (IAmAI) <dan.stevens.iamai@gmail.com> wrote:
>Could someone explain why the following code raises ArgumentError. Thanks.
>
>class SuperClass
>
> def initialize #Make sure you spell 'initialize' correctly!
>...
>
>class SubClass < SuperClass
>
> def initialize(data1, data2)
> super

This should be super(). Without the parenthesis it defaults to passing
the arguments given to the current method to the super class's
implementation.

Ah, parentheses do the trick. I always helped me calling

    super *

what is not actually readable or beautiful.

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Thanks all of you for clearing that up. In ruby I'm used not using
parenthesis when calling methods without parameters, but I should be
able to remember this exception :slight_smile:

···

On 02/04/07, Bertram Scharpf <lists@bertram-scharpf.de> wrote:

Hi,

Am Dienstag, 03. Apr 2007, 05:59:31 +0900 schrieb Ryan Leavengood:
> On 4/2/07, Dan Stevens (IAmAI) <dan.stevens.iamai@gmail.com> wrote:
> >Could someone explain why the following code raises ArgumentError. Thanks.
> >
> >class SuperClass
> >
> > def initialize #Make sure you spell 'initialize' correctly!
> >...
> >
> >class SubClass < SuperClass
> >
> > def initialize(data1, data2)
> > super
>
> This should be super(). Without the parenthesis it defaults to passing
> the arguments given to the current method to the super class's
> implementation.

Ah, parentheses do the trick. I always helped me calling

    super *

what is not actually readable or beautiful.

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de