Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Leaving a constructor midway?

by Abigail-II (Bishop)
on Oct 22, 2003 at 14:23 UTC ( [id://301220]=note: print w/replies, xml ) Need Help??


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

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

Replies are listed 'Best First'.
Re: Leaving a constructor midway?
by dragonchild (Archbishop) on Oct 22, 2003 at 14:44 UTC
    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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://301220]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2024-04-25 06:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found