On Thu, Oct 23, 2003 at 06:48:29AM -0700, R. Joseph Newton wrote:
> "Randal L. Schwartz" wrote:
> > >>>>> "Dan" == Dan Anderson <[EMAIL PROTECTED]> writes:
> >
> > Dan>   my $class = ref($proto) || $proto;
> >
> > Don't do this!
> 
> I'm still a little mystified as to what you find offensive there.

[snip]

> I'll grant that I have sometimes felt silly having that construct in a root
> class, but so far it has not done any actual damage.

There are two things going on --

First, the constructor is taking the classname from the first argument,
like this:

    sub new {
      my $class = shift; 
      my $self = { initial => 'data' };
      bless $self, $class;
    }

There's nothing wrong with that, and in fact it's *necessary* if a derived
class wants to inherit the new() method from Foo.  So don't feel silly about
using "my $class = shift" in a root class!  That's where you really need to
be using it.

But the constructor is also prepared to take an object as the first argument
instead of just the classname-as-a-string.  This is explained in perltoot:

    While we're at it, let's make our constructor a bit more flexible.
    Rather than being uniquely a class method, we'll set it up so that it
    can be called as either a class method or an object method.  That way
    you can say:

        $me  = Person->new();
        $him = $me->new();

    To do this, all we have to do is check whether what was passed in was a
    reference or not.  If so, we were invoked as an object method, and we
    need to extract the package (class) using the ref() function.  If not,
    we just use the string passed in as the package name for blessing our
    referent.

        sub new {
            my $proto = shift;
            my $class = ref($proto) || $proto;

And then Tom uses "ref($proto) || $proto" in all the following examples.

There's no *functional* problem with doing this; it's not going to break 
anything, and if users of your class don't use "$obj->new" then the
"ref($proto)" stuff won't do anything at all.

But what seems to be a problem is that lots of people got the impression
that a) this has something to do with inheritance -- which it doesn't --
and that b) it's somehow *obligatory*; that if you forget to check
"ref($proto)" your constructor is broken.

Now, I don't particularly like "$obj->new", but it's not really "wrong"
either.  If you want to let people call your constructor that way, then
go ahead and use "ref($proto) || $proto".  And conversely, if you think
"$obj->new" is an abomination, then just use "my $class = shift".

But either way, make an informed decision.  Don't cargo-cult it in
because it's in the examples in perltoot.  And don't cargo-cult it out
because Randal smacks you whenever you use "ref($proto)" in public.

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to