in reply to Philosophy of a "new" method

I'd second CountZeros suggestion to check out Moose, if only for getting a different perspective on OO programming styles.
Apart from that, this really is a matter of style and also of the interface you want to your class. For example, you might have a class DataAnalyzer that does some calculations on data from a database. One interface to this could look like this:
my $da = DataAnalyzer->new(); $da->connect_to_db->($dsn); my $result_set = $da->run_analysis( %parameters_for_analysis );
But this probably connects to the same database every time, so it might make more sense to initiate the object with the database parameters straight away, i.e. set up the connection in the 'new' method so that the API becomes:
my $da = DataAnalyzer->new( $dsn ); my $result_set = $da->run_analysis( %parameters_for_analysis );
Now the 'new' method does a bit moe work (set up the actual connection) but it seems to make more sense from the user's perspective.
Or, if you find that the new method should return results straight away because it is unlikely that this will ever be run twice with different parameters on the same database anyway. Now your new method will run the analysis and return some sort of result immediately (this may not be the best example but nevertheless...):
my $result_set = DataAnalyzer->new( $dsn, \%parameters_for_analysis ) +;
Whether or not you use an '_init' method is really just matter of style: it certainly helps to de-clutter the 'new' method itself and keep it short in cases where a lot of setting-up has to be done.

Replies are listed 'Best First'.
Re^2: Philosophy of a "new" method
by JavaFan (Canon) on Feb 04, 2011 at 17:23 UTC
    Whether or not you use an '_init' method is really just matter of style
    I strongly disagree with an '_init' method just being matter of style. That's like saying "Whether or not a language has hashes is just a matter of style".

    Suppose you have classes with the following new methods:

    package FloorWax; sub new { my $class = shift; bless {FW_massage(@_)}, $class; } package DessertTopping; sub new { my $class = shift; bless {DT_massage(@_)}, $class; }
    And now you need to create something that's both a DessertTopping and a FloorWax, using two corner stones of object oriented programming: code reuse and encapsulation.

    Sure, the start is easy:

    package FloorToppingDessertWax; our @ISA = qw[FloorWax DessertTopping]; sub new { my $class = shift;
    But then what? Without breaking encapsulation, how do you set up the object so it's both a FloorWax, and a DessertTopping? If you call FloorWax->new you get a configured FloorWax object, without the DessertTopping attributes. And if you call DessertTopping->new, you will be missing the FloorWax attributes.

    If instead, you had:

    package FloorWax; sub new {bless {}, shift} sub init { my $self = shift; my %arg = FW_massage @_; @$self{keys %arg} = values %arg; $self } package DessertTopping; sub new {bless {}, shift} sub init { my $self = shift; my %arg = DT_massage @_; @$self{keys %arg} = values %arg; $self }
    Things would be a lot easier. You could write a derived class as:
    package FloorToppingDessertWax; our @ISA = qw[FloorWax DessertTopping]; sub new {bless {}, shift} sub init { my $self = shift; foreach my $class (@ISA) { my $init = "${class}::init"; $self->$init(@_) if $self->can($init); } $self; }

    So, I argue that having or not having an _init method isn't a matter of style. Having an init (not really an _init, as it should be called from the outside) makes your class more (re)usable.

      hmmmmmm, I don't think I agree with that. For a start, you are talking about a public method 'init' instead of the private '_init' that is usually used as a sort of extension to 'new' to do the actual heavy lifting. That in itself is a choice of style isn't it?
      I would also argue (again a matter of preference and style) that FloorWaxDessertTopping might be better off inheriting from a ThingsThatCanGoOnTopOfOtherThings base class if it's parents are so different.
      Or of course you could use Moose and define a role CanGoOnSomething or something along those lines...
        Public of course. Having new call private methods doesn't solve anything, and certainly isn't a choice of style. (Unless you have the bottom _init call SUPER::_init, but then it isn't private anymore, is it?)

        I would also argue (again a matter of preference and style) that FloorWaxDessertTopping might be better off inheriting from a ThingsThatCanGoOnTopOfOtherThings base class if it's parents are so different.
        Rewriting classes into different classes so "it's better off inheriting" isn't code reuse, is it? It "reinventing the wheel".

        Code reuse is this: Given some code, possibly written by something else, (re-)use it. Code reuse isn't "Hmmm, here's some code I may be able to reuse. Let's rewrite it for scratch, but then differently". The FloorWax and DessertToppings are given. Maybe written by your team member. Maybe written by some other department. Maybe you found it on CPAN.