jeanluca has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks
I was reading some interesting perl code and saw the following line
sub new { my $cname = shift; my $class = ref($cname) || $cname;
I don't understand what is happening here. Why not:
sub new { my $class = shift ; .....
Thanks in advance
Luca

Replies are listed 'Best First'.
Re: Objects and references
by jeffa (Bishop) on Sep 29, 2005 at 16:04 UTC
Re: Objects and references
by philcrow (Priest) on Sep 29, 2005 at 16:13 UTC
    Your suggested form my $class = shift; is used when you know the method will only be called through the class name. The other form lets you call the method through the class name or through an existing object.

    The ref method returns the class name. It will return undef if it's argument is not a ref, in which case the || will give the class name.

    In the discussion mentioned above, people debate whether this is good form or not. I tend to say you should not make methods with multiple calling conventions, but Perl is about freedom and many wise programmers disagree with me.

    Phil

Re: Objects and references
by sauoq (Abbot) on Sep 29, 2005 at 16:15 UTC

    That extra bit of code there is to get the constructor to work as both an object method and a class method. I.e. it allows the user of the class to write my $newobj = $someobj->new(); or the more familiar  my $newobj = ThisClass->new();. Some people (I'm one) think this isn't really a good idea most of the time.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Objects and references
by dragonchild (Archbishop) on Sep 29, 2005 at 16:52 UTC
    I prefer to do something as such:
    use Scalar::Util qw( blessed ); sub new { my $class = shift; return $class->clone( @_ ) if blessed $class; # Continue on with constructor. } sub clone { my $self = shift; return $self->new( @_ ) unless blessed $self; # Continue on with cloner. }

    Otherwise, I document what my methods expect and laugh at the people who don't RTFM.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      Ok, that makes sense! But all this can be solved if you do:
      package PackageName ; sub new { $class = shift ; return bless {}, PackageName ; }
      This way you don't care if $class is a reference or not!
      Luca
        This way you don't care if $class is a reference or not!

        And you don't allow people to subclass your class.

        Plus, if you're going to do that, do it right:

        sub new { return bless {}, __PACKAGE__; }

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?