http://qs321.pair.com?node_id=329829


in reply to Re: Re: Reducing Perl OO boilerplate
in thread Reducing Perl OO boilerplate

I'll cut off the people who will tell you, don't use new, since if you have a function called new in your main:: space, it'll break your program.

Uh, no. Although there is no rule that OO constructors be called "new" it's a pretty standard convention. Some modules (notably DBI) use an alternative constructor name, but it certainly does NOT break anything if you have a subroutine named "new" in package main.

Why would you have a funciton called new? New what? New time of day? New cheese?
It's a constructor. It makes a new object. That's why it's called new.

As for the original question, I'm rather fond of Class::MethodMaker. Works for me, though YMMV.

Gary Blackburn
Trained Killer

  • Comment on Re: Re: Re: Reducing Perl OO boilerplate

Replies are listed 'Best First'.
Re: Re: Re: Re: Reducing Perl OO boilerplate
by exussum0 (Vicar) on Feb 18, 2004 at 12:31 UTC
    Nononon.. you missed the point. If I have a program that uses class Foo, and in my program somewhere else, i declare sub new, doing new Foo will break. It's not "why is the constructor called new" but if you do "new Foo" and new() exists on the same scope of your program. Take this for example:
    use Foo; sub new(*) { die "wuh?"; } $x = new Foo();
    With a package..
    package Foo; sub new { return bless { a => 1 }, shift; } sub new2 { return bless { a => 1 }, shift; } 1;
    new2 works, new breaks. THAT is my point. Why would anyone do this, I don't know. But people have pointed out that ->new is the better convention.

    So before you berate me more on what a constructor is, i suggest you reread my posts. Thank you.


    Play that funky music white boy..
Re: Re: Re: Re: Reducing Perl OO boilerplate
by flyingmoose (Priest) on Feb 18, 2004 at 14:55 UTC
    Class::MethodMaker appears to be exactly what I want in terms of defining data. Good find. I need to still do some exploring to find what I can do in terms of constructor cleanup (so that I don't need to call object methods to set all of the variables after 'new' is invoked .. aka constructors that take parameters like they are supposed to), but this will help with method cleanup quite a bit. Thanks!
      I've had to do exactly that with Class::MethodMaker. I needed to initialize an object with a LOT of data (and a LOT of method calls) and initializing the object through repeated method calls was S-L-O-W. So, I subverted the regular constructor with my own:
      package Datawarehouse::Employee; use Class::MethodMaker new_with_init => 'new'; sub init { # ...Load up a whole lot of data # Bless my own object into the class Datawarehouse::Employee->new_new(\%args); } sub new_new { # This constructor is a HELL of alot faster than creating an # object by calling accessor methods one by one. my $class = shift; my $args = shift; my $obj = bless $args, $class; # Loading the whole hash as one }

      If you do this while using the key_attrib parameter in Class::MethodMaker you'll need to call the key_attrib method explicitly so that your hand-made object is tracked like the regular one's are. Looking at the Class::MethodMaker source code is a great way of figuring out exactly what's going on with the autogenerated methods.

      Gary Blackburn
      Trained Killer

        Just combing through the POD, I ran across this.

        new_hash_init Creates a basic constructor which accepts a hash of slot-name/value pairs with which to initialize the object. The slot-names are interpreted as the names of methods that can be called on the object after it is created and the values are the arguments to be passed to those methods. Takes a single string or a reference to an array of strings as its argument. For each string creates a method of the form listed below. Note that this method can be called on an existing objec, which allows it to be combined with new_with_init (see above) to provide some default values. (Basically, declare a new_with_init method, say 'new' and a new_hash_init method, for example, 'hash_init' and then in the init method, you can call modify or add to the %args hash and then call hash_init.)
        sub <string> { my ($class, %args) = @_; my $self = {}; bless $self, $class; foreach (keys %args) { $self->$_($args{$_}); } $self; }

        Sounds like new_with_init except with my name/value pairs request taken into account. Excellent tip. Rock on!