in reply to Re: OO: Leaving a constructor midway?
in thread OO: Leaving a constructor midway?

(I'm going to regret doing this, but what the hey!)

The magicking action in Perl may be bless. But, OOD/OOP are language-independent concepts. The fact that Perl has certain quirks in how it implements OO (as opposed to the C++ or Java quirks) should be irrelevant to a discussion of OO technique.

The "popular way" of using a subroutine called as a class method that returns a blessed reference also happens to be a rather decent implementation of an OO design for constructing an object. Your statement about "on the language level" is irrelevant to the discussion. On the language level, C++ reuses a ton of C features that are not OO. So does Perl. So what?!?

OP is calling some class method sub (presumably named new) as a constructor. His program calls it, probably with some set of values, and gets back something that looks, talks, and walks like an object. Sounds like a constructor to me? The fact that, under the hood, it calls bless is completely irrelevant to the client code. In fact, a number of programmers use OO Perl without ever knowing about bless.

------
We are the carpenters and bricklayers of the Information Age.

The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

... strings and arrays will suffice. As they are easily available as native data types in any sane language, ... - blokhead, speaking on evolutionary algorithms

Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Replies are listed 'Best First'.
Re: Leaving a constructor midway?
by Abigail-II (Bishop) on Oct 22, 2003 at 14:23 UTC
    my $snickle = CGI -> new; package Gonbagger; sub one {bless [] => "Fumble"} sub two {one} sub three {two} sub four {$snickle}
    All four subs return a blessed object. Do you call all of them constructors? Would you call an accessor method that happens to return an object (instead of say a string or a number) a constructor? After all, the returned value is something that "looks, talks, and walks like an object." Client code doesn't know what's going on under the hood.

    Java and Ruby have methods that are constructors. They are special, in the sense that they are called implicitely, and can't/shouldn't be called directly. Unlike Perl's class methods that just happen to return an object.

    What if I write my class like this:

    package Lioger; use Exporter (); @Lioger::EXPORT = qw /lioger1/; @Lioger::ISA = qw /Exporter/; sub lioger1 { return if @_; my $x = bless [] => __PACKAGE__; $x [0] = $x; } sub lioger2 { ${$_ [0]} [0] }
    Are both methods constructors?

    Language like Java, Ruby and C++ don't call just any function that happens to return an object a "constructor".

    Abigail

      Definition of Constructor:

      The constructor is a member function of a class. It is invoked every time an object is created. ...

      I would add to the above that a constructor is a method by which a new object is created from whole cloth. It satisfies the need of the client to have a new instance of such-and-such a class.

      By that definition, your Gonbagger methods one(), two(), and three() are all constructors, as is the lioger1 method from the second example. Gonbagger::four() is not a constructor because it doesn't construct anything. Neither is the lioger2() method.

      The fact that bless is required to construct an object does not equate to bless being used solely for object construction.

      package Foo; sub new { bless [], $_[0] } sub confuse { bless $_[0], 'ARRAY' }

      Surely, you're not going to tell me that confuse() is using bless as a constructor?!? I don't care what it's doing in the innards of the interpreter - I am not using bless there to create a new object, hence confuse() is not a constructor.

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      ... strings and arrays will suffice. As they are easily available as native data types in any sane language, ... - blokhead, speaking on evolutionary algorithms

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

        Definition of Constructor:

        The constructor is a member function of a class. It is invoked every time an object is created. ...

        Surely none of the examples I gave that you call "constructors" are invoked if a new object is created. They are called, and just happen to return an object (which may, or may not, be constructed using 'bless'). Consider the following function:

        sub foo { rand (2) < 1 ? 0 : bless [] => "foo" }
        Would that be a Schr\"odinger cat constructor?
        By that definition, your Gonbagger methods one(), two(), and three() are all constructors, as is the lioger1 method from the second example. Gonbagger::four() is not a constructor because it doesn't construct anything. Neither is the lioger2() method.
        But the client code doesn't know what's going on under the hood, and to quote you:
        The fact that, under the hood, it calls bless is completely irrelevant to the client code.

        package Foo; sub new { bless [], $_[0] } sub confuse { bless $_[0], 'ARRAY' }
        Surely, you're not going to tell me that confuse() is using bless as a constructor?!?
        Of course it is. It's making a new instance of the class "ARRAY". You might quibble that $_ [0] might already be an instance of the class 'ARRAY' and therefore it's not constructing a new object, but that's as useful as arguing that $x = 17; isn't an assignment if the value of $x happens to be 17.

        Abigail

        I think it's just a distinction between a factory method and a constructor. Perl gives you factory methods. You have to explicitly return your 'object' at the very end of your 'constructor'. Whereas the traditional notion of a constructor is something that implicitly returns itself and all you need to do is ensure that your object is in a suitable initial state.

        Factory methods are just as flexible though and I usually favor them over constructors anyway since they give you a lot more control over what specific object you are creating. For instance, a factory method can create and return a specific subtype of the object you want and you can swap out that specific subtype (to change underlying implementation) easily without breaking client code. Similarly with turning a class into a singleton.