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

Monks, In reading the Perl OO tutorial perltooc I noted this code in the Indirect References to Class Data section:
package Some_Class; our($CData1, $CData2); sub new { my $obclass = shift; return bless my $self = { ObData1 => "", ObData2 => "", CData1 => \$CData1, CData2 => \$CData2, } => (ref $obclass || $obclass); }
My question is about the use of the => comma like operator.

Why?

sub new { my $class = shift; return bless my $self = {}, (ref $class || $class); }
seems to work just as well.

Does anyone know of any reason why => might be used in place of , in this instance?

Interestingly, this has let to a clarification on the meaning of => for me.

I had always assumed that => stringifies its left operand, but a little testing, seems to indicate it only actually stringifies if it thinks the left operand is a word... i.e. not a $var - subtle!

Regards,

Jeff

Replies are listed 'Best First'.
Re: bless with => separated args
by blazar (Canon) on Aug 01, 2005 at 08:49 UTC
    Does anyone know of any reason why => might be used in place of , in this instance?
    There's no particular reason apart readability/psychological feeling. Here you have a large structure applied -this is the keyword!- by bless to the class you want to bless it into. You often use => instead of , when you want to stress that the term on the left is applied or associated to that on the right.
    I had always assumed that => stringifies its left operand, but a little testing, seems to indicate it only actually stringifies if it thinks the left operand is a word... i.e. not a $var - subtle!
    Indeed it stringifies only in a few situations and in some cases this has led to confusion.

    Incidentally, it may be a matter of personal preference/style, but this:

    return bless my $self = {}, (ref $class || $class); # ^^^^^^^^^^^^^^^^^^^^^^
    is deprecated by many kwnoledgeable OO Perl hackers.
      Thanks for the detail on fat-comma.

      Any reason why "(ref $class || $class)" is deprecated?

      It is useful if you want a new instance based on the same class as an existing object, without having to hard-code the class name.

      The only reason that I have heard is that most people start OO by copying the examples, without understanding the code, which surely is not a strong enough reason for deprecation?

      Regards,

      Jeff

        Any reason why "(ref $class || $class)" is deprecated?

        It can make the semantics of your constuctor confusing. If I want a new object of class Foo then I want to call Foo->new. I'd probably expect $foo->new to clone $foo, but if the class author wanted that functionality they should have created an object method called "clone" or something like that.

        In general, it's a good idea to have class methods and object methods completely separate from each other. The ref $class || $class idiom breaks that distinction.

        It is useful if you want a new instance based on the same class as an existing object, without having to hard-code the class name.

        Well, you can always use (ref $foo)->new if that's what you want.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        I'm far from being an OO expert myself, but the basic reason is that they think that new() should be used as a class method and that an instance method to provide cloning should be supplied instead, to keep their roles/functionalities separated, so as to avoid possible confusion.
        Deprecated implies they once endorsed it.

        Writing ref $proto || $proto allows the caller of the constructor to create a new object by calling:

        $obj -> new;
        Some people (who are seen as "knowledgable") claim that $obj -> new confuses the hell out of them and that hence constructors should not contain ref $proto || $proto.

        I think that's silly. If something confuses you, don't use it. No need to jihad the thing that enables you to get confused.

Re: bless with => separated args
by davorg (Chancellor) on Aug 01, 2005 at 09:06 UTC

    I've seen the "fat comma" used in a number of situations like this, where it can be said to indicate that its left operand "becomes" its right operand in some way.

    Fans of this usage think that it makes their code clearer. I strongly suspect that, in most cases, the opposite is the case. In my opinion using the fat comma for anything other than hash initialisation can be very confusing. And in his new book Damian seems to agree with me as he strongly suggests only using it for defining key/value pairs.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: bless with => separated args
by jaa (Friar) on Aug 01, 2005 at 08:45 UTC
    FYI, here is my test on whether the => operator stringifies its left operand, if the lop is an object:
    my $obj = Stringy->new( 'the look' ); my $counter = 0; for my $it ( a1 => $obj => 2 => 3 => 4, 5 ) { $counter++; print "iteration: $counter "; print "with (" . $it . ")"; print "\n"; } #------------------------------------------------------- package Stringy; use strict; use overload ( '""' => \&toString, ); 1; sub new { my $class = shift; my $self = { appearance => shift, }; return bless $self, $class; } sub toString { my $self = shift; print "[toString called] "; return $self->{appearance}; }
    Run this, and you'll note that the object is stringified during the print as expected.

    Comment out the 'print "with...' line, and you will note that the object is never stringified, not even by the => operator in the for (...) list.

Re: bless with => separated args
by Anonymous Monk on Aug 01, 2005 at 10:49 UTC
    Beside the effect of allowing bare words (things that look like an identifier) on its left hand side, a fat arrow has no semantic or syntax difference with a comma. It looks different.

    Some people use it to separate function arguments that play different roles, a subset of those only after the first argument. For instance, in (s)printf, the first argument (if there's no file handle argument) is a format, the rest a list. Writing

    printf $format => $arg1, $arg2, $arg3;
    emphasis the fact the first argument is "special".

    It's a matter of style. Use it if you like it, don't use it if you don't.