in reply to Re: Philosophy of a "new" method
in thread Philosophy of a "new" method

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.

Replies are listed 'Best First'.
Re^3: Philosophy of a "new" method
by tospo (Hermit) on Feb 07, 2011 at 09:34 UTC
    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.

        Sure, if this is what you have been given and you can't change it then I would not rewrite the whole class architecture either. I was more refering to a situation where you do make the choices. Anyway, I don't think I'm the only one who ever used a private _init method and I also wouldn't say that there arent' scenarios where a public init method isn't the right way to go. That's what I meant with choices of design/style.