Stefano Crocco
7/4/2008 2:37:00 PM
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