[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

initialize and super with parameters

Andy Joel

7/4/2008 2:27:00 PM

Some example code

class MySuperClass
def initialize *args
puts "In SuperClass initialize"
end
end

class MySubClass1 < MySuperClass
def initialize name
puts "In SubClass initialize: " + name
super
end
end

The super in the subclass will take with it any parameters that were
sent to the initialize method, so this will throw an error as the
initialize in MySuperClass does not accept the same number of
parameters.

This is surprisingly restrictive (given the nature of Ruby generally).
If you are extending a class with a parameterless initializer, you
cannot access the superclass initializer if you want to include a
parameter.

The initialize method is automatically private (and appears to be stuck
like that), so cannot be invoked through super.initialize or something
like that.

Three possible workarounds: When you create an initialize method, always
have a parameter with a default value, even if you just discard it. This
will allow subclasses to have zero or one parameters, and effectively
any number through a hash. A better way perhaps is to use *args as the
parameter list, even if you do not use it. If you cannot modify the
superclass (say it is in someone else's API), the nly alternatiove I can
think of is to initialise with another method, say init, but then you
are relying on any API user remembering to do that - the whole point of
initialize is so they (and you) do not have to remember.

These are all hacks. Is there a better way? Or have I missed something?
--
Posted via http://www.ruby-....

4 Answers

Stefano Crocco

7/4/2008 2:37:00 PM

0

On Friday 04 July 2008, Andy Joel wrote:
> Some example code
>
> class MySuperClass
> def initialize *args
> puts "In SuperClass initialize"
> end
> end
>
> class MySubClass1 < MySuperClass
> def initialize name
> puts "In SubClass initialize: " + name
> super
> end
> end
>
> The super in the subclass will take with it any parameters that were
> sent to the initialize method, so this will throw an error as the
> initialize in MySuperClass does not accept the same number of
> parameters.
>
> This is surprisingly restrictive (given the nature of Ruby generally).
> If you are extending a class with a parameterless initializer, you
> cannot access the superclass initializer if you want to include a
> parameter.
>
> The initialize method is automatically private (and appears to be stuck
> like that), so cannot be invoked through super.initialize or something
> like that.
>
> Three possible workarounds: When you create an initialize method, always
> have a parameter with a default value, even if you just discard it. This
> will allow subclasses to have zero or one parameters, and effectively
> any number through a hash. A better way perhaps is to use *args as the
> parameter list, even if you do not use it. If you cannot modify the
> superclass (say it is in someone else's API), the nly alternatiove I can
> think of is to initialise with another method, say init, but then you
> are relying on any API user remembering to do that - the whole point of
> initialize is so they (and you) do not have to remember.
>
> These are all hacks. Is there a better way? Or have I missed something?

You want to use

super()

instead of just

super

It is one of the few situations (if not the only) where adding the parentheses
to a method call changes its behavior. In particular, super without
parentheses calls the method of the base class with all the arguments passed
to the current method; super() instead calls the method of the base class
without arguments.

Stefano

benjohn

7/4/2008 2:47:00 PM

0

> You want to use
>
> super()
>
> instead of just
>
> super
>
> It is one of the few situations (if not the only) where adding the
> parentheses
> to a method call changes its behavior. In particular, super without
> parentheses calls the method of the base class with all the arguments
> passed
> to the current method; super() instead calls the method of the base class
> without arguments.
>
> Stefano

Note that you can also call the inherited initialize with any other
parameters if you like, such as:

super(:cactus, :fridge_magnet, Caribu.new, {:args_in=>some_args_i_got})

So it's pretty felxible, really :-)

Cheers,
Benjohn



Chuck Remes

7/4/2008 2:54:00 PM

0


On Jul 4, 2008, at 9:26 AM, Andy Joel wrote:

> Some example code
>
> class MySuperClass
> def initialize *args
> puts "In SuperClass initialize"
> end
> end
>
> class MySubClass1 < MySuperClass
> def initialize name
> puts "In SubClass initialize: " + name
> super
> end
> end
>
> The super in the subclass will take with it any parameters that were
> sent to the initialize method, so this will throw an error as the
> initialize in MySuperClass does not accept the same number of
> parameters.
>
> This is surprisingly restrictive (given the nature of Ruby generally).
> If you are extending a class with a parameterless initializer, you
> cannot access the superclass initializer if you want to include a
> parameter.

Take a look at FAQ 5.9 here for your answer [1]. The call to "super"
is not a real method call. When you call "super" without any params or
parentheses, it starts the method lookup for the current method name
but starting in the superclass while passing along all parameters (if
any). If the superclass' method signature is different, you must
explicitly tell super what to pass. If there are no parameters at all,
empty parens () are sufficient.

class A
def initialize
puts "superclass"
end
end

class B < A
def initialize(name)
puts "my name is #{name}"
super # <== wrong
end
end

B.new("Chuck")

This will throw an ArgumentError. Change the subclass like so:

class B < A
def initialize(name)
puts "my name is #{name}"
super()
end
end

B.new("Chuck")

All is well with the world.

cr

[1] http://www.math.ias.edu/doc/ruby-docs-1.8.2/faq-en/ruby...

Andy Joel

7/4/2008 9:13:00 PM

0

Stefano Crocco wrote:
> You want to use
>
> super()
>
> instead of just
>
> super
>
> It is one of the few situations (if not the only) where adding the
> parentheses
> to a method call changes its behavior. In particular, super without
> parentheses calls the method of the base class with all the arguments
> passed
> to the current method; super() instead calls the method of the base
> class
> without arguments.
>
> Stefano

Thanks for the prompt replies everyone. So I had just missed something,
which is good news.
--
Posted via http://www.ruby-....