SPUG:Object property question

Fred Morris m3047 at inwa.net
Sun May 4 21:53:20 CDT 2003


Sure, the prototype is ignored by Perl. But you didn't ignore it, and it
probably conveyed the intended meaning: "new is called with something which
is not optional (in the case under discussion the class name), and
depending on your mess one or more arguments.. of course all arguments are
optional to Perl itself, if you want them then you yourself must impress
meaning on them."

Or dispensing with sophistry: the class is always implicitly passed as the
first argument if you call it with the originally given syntax, and the
other arguments are whatever you've decided your own method needs.

Colin Meyer wrote:
>On Fri, May 02, 2003 at 05:24:08PM -0700, Fred Morris wrote:
>
>
>[...]
>
>> How about..
>>
>> sub new ($;$$$ ) {
...........^^^^^^^

He's referring to this.

>>
>>   return SUPER::new( @_ );
>>
>> }
>>
>> or...
>
>Note that if you call your constructor in the typical OO fashion:
>
>  my $obj = ClassName->new();
>
>then the prototype will not apply.

But it will work. And the prototype does no harm; and in fact if you call
the constructor from within the module directly as a subroutine (for some
unknown reason) it will apply.


Now that raises an interesting question: if there's a prototype for the
MOAM's new(), then given the above syntax is it applied? Ahh yes.. I think
intuitively the answer is a resounding "yes", because you're calling it as
a subroutine in a different namespace, not as a method.. unless there's
some special voodoo about SUPER, of course.


So, let's follow the SuSE maxim to have a lotta fun and test it, shall we?
With a prototype for MOAM::new( $$ ), and using $class = shift in the
subclass:


    # Fails

    return SUPER::new( $class, 'x' );

My bad! Peculiarly, I tend to avoid SUPER unless I really mean it, as in:
"Is there anybody out there who wants to take a stab at this? Because I
really don't have a clue, I'm just hoping." Well ok, not really, but I do
recite the "How many OO programmers does it take to change a lightbulb"
joke as a mantra at times like these.

    # Returns 'COAM' instead of 'x'

    $class->SUPER::new( $class, 'x' );

    # Works

    $class->SUPER::new( 'x' );

Clearly what we're seeing here is that SUPER only works with method calls.
(But going all the way back to what started this thread, note that this is
a class reference and not a blessed reference... so yes you can call a
member method on an unblessed reference... as long as that reference is to
the class. Just remember that a class ain't no object!)

    # Works

    return MOAM::new( $class, 'x' );

(BTW, this example was also given in my original post, although it wasn't
quoted in the reply.)

    # Fails the prototype

    return MOAM::new( $class, 'x', 'y', 'z' );

Philosophically, if you prototype constructors, should you be specifying
the superclass? In a language with multiple inheritance I tend to say yes;
practically speaking, the answer which Perl gives up is unequivocally yes.
Philosophically speaking if you use multiple inheritance and you don't
prototype your constructors (either in the compiler or the style guide),
exactly what sort of outcome are you expecting?


In conclusion you can read what's written in perldoc as a complaint about
the shortcomings of prototypes, or as a subtle and zen-like observation on
the pitfalls of multiple inheritance and cavalier use of SUPER, and
suggestion on exactly how to call your superclass constructors; as "they"
say TMTOWTDI.. and as I say TAMWTDIR.

Now that raises an interesting question: since I'm calling MOAM out by
name, what happens if MOAM in turn inherits its constructor from FOAM? Ahh
yes.... what do you think happens? Well, it fails. Of course Java just
decided to dispense with multiple inheritance entirely, if you want to
inherit from multiple classes.. you can't.

Now that raises an interesting question: how you do make an object take on
the attributes of multiple classes if you can only inherit from one? Ahh
yes...

Well of course at the end of the day, Perl's prototyping is weak: if you
use the $obj->method() syntax, your prototypes aren't checked. But if it's
important to check, you can, you only have to use Class::method( $obj ) is
all. (How does that joke go? "... None. Invoke the proper method and the
lightbulb will change itself.")

>Have fun,
>-Colin.

:-p

--

Fred Morris
m3047 at inwa.net





More information about the spug-list mailing list