in reply to Re^2: bless with => separated args
in thread bless with => separated args

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

Replies are listed 'Best First'.
Re^4: bless with => separated args
by Anonymous Monk on Aug 01, 2005 at 11:04 UTC
    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.
    That, I do not understand. If you expect the author to name clone functionality clone, then why assume that new clones the object?

    I'd expect something called new to give me a new thing - not a cloned one.

    Well, you can always use (ref $foo)->new if that's what you want.
    That's not much of an argument, is it? With such an argument, we could do away with for/foreach, unless, and/or, q/qq/qw/qx, etc. There are always alternatives taking a few more keystrokes.

    And note that the existance of ref $proto || $proto in a constructor doesn't prevent you from writing:

    (ref $foo)->new
    if
    $foo->new
    confuses you.

    But the absense of ref $proto || $proto forces someone who doesn't confuse easily to write:

    (ref $foo)->new
    Ergo, using ref $proto || $proto gives the user of the module more choice.

      My point was that $foo->new has confusing semantics. It should mean something like "create a new object based on $foo" not "create a new object of the same class as $foo". Who knows whether $foo->new creates a new, empty object of the same class or a complete copy of $foo. It's not clear unless you read the docs or the source code. I didn't say that I was confused, just that it was potentially confusing :)

      Good OO programming practice is that class methods and object methods should be distinct. I think that it's a shame that common Perl practice seems to be to ignore that practice as it makes OO programming in Perl seem more complex than it needs to be.

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

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

        Who knows whether $foo->new creates a new, empty object of the same class or a complete copy of $foo. It's not clear unless you read the docs or the source code.
        Well, unless you read the docs or the source code, you don't know whether
        Class->new
        returns an object of class Class, or something else.

        Or more generally, unless you read the docs or the source code, you don't know what random_function or random_method is going to return anyway.

        OTOH, I've yet to encounter code where

        Class->new
        isn't a constructor of the class Class, or to encounter code where
        $foo->new
        was called, and it returned something else than (ref $foo)->new.
        Good OO programming practice is that class methods and object methods should be distinct. I think that it's a shame that common Perl practice seems to be to ignore that practice as it makes OO programming in Perl seem more complex than it needs to be.
        Man, of all the problems of doing OO in Perl, the lack of separation between class and object methods looks incredibly minor to me.