Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: OO Perl: calling a constructor within a class

by Anonymous Monk
on Sep 28, 2001 at 00:34 UTC ( #115246=note: print w/replies, xml ) Need Help??


in reply to OO Perl: calling a constructor within a class

Yet another solution would be to use Class::Multimethods, and have both constructors named new:
package MyClass; use Class::Multimethods; multimethod new =>('$') => sub { my ($class) = @_; bless { name => '', rank => '', cereal_number => '', }, $class; } multimethod new =>('$','$','$','$') => sub { my ($class, $name, $rank, $c_num ) = @_; bless { name => $name, rank => $rank, cereal_number => $cnum, }, $class; }
BTW, there'll be a new version of Class::Multimethods out in the next month or two that lets you define multimethods like they will (probably) be written in Perl 6:
package MyClass; use Class::Multimethods::Attributes; sub new :multi ($class) { bless { name => '', rank => '', cereal_number => '', }, $class; } sub new :multi ($class, $name, $rank, $c_num) { bless { name => $name, rank => $rank, cereal_number => $cnum, }, $class; }
Damian

Replies are listed 'Best First'.
Re: Re: OO Perl: calling a constructor within a class
by dragonchild (Archbishop) on Sep 28, 2001 at 00:50 UTC
    I'm not sure I like this polymorhic method-naming stuff that'll be happening in the background. Perl is weakly-typed, so why do a work-around that strongly-typed languages have to do? Instead, why not do the following?
    sub new { my ($class, $name, $rank, $c_num) = @_; $name ||= ''; $rank ||= ''; $c_num ||= ''; bless { name => '', rank => '', cereal_number => '', }, $class; }
    That, to me, just feels cleaner and is more maintainable. If you make a change in new(), you only have to change it in one place. Especially if it's in a base class. If it's in a base class and you only change one, you suddenly have weird behavior in the grandchild classes and debugging it would take an age-and-a-half. *shudders*

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

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Careful with that ||=, Eugene!
      Did you really want to prohibit a cereal number of zero?

      That's why I generally avoid using ||= to specify defaults.
      Unless I'm very sure my incoming data won't ever be 0, "0", or "".

      Besides, there are ways to tell if she is a witch:

      $name = '' unless defined $name; $rank = '' unless defined $rank; $c_num = '' unless defined $c_num;
      or:
      foreach ($name, $rank, $c_num) { defined or $_ = '' }
      or the strange-but-lovely:
      $_ = '' for grep !defined => ($name, $rank, $c_num);
      or the tried and true:
      $name = '' if weight($name) == weight($duck); $rank = '' if weight($rank) == weight($duck); $c_num = '' if weight($c_num) == weight($duck);

      Err...

      Oh, yes, I should also mention that next week, when Apocalypse III and Exegesis III appear, you'll find that Perl 6 is going to have a much nicer way to solve this problem.

      Damian

        Perl 6 is going to have a much nicer way to solve this problem.

        I like the sound of that... last I heard there was some strong opposition to an ||= that tests for definedness rather than truthfulness. I've always been on the side of having such a construct, especially since ||= is so tempting for newbies to use, even *after* they've been told of the pitfalls.

        The only remaining question is what will the operator look like?

        -Blake

      I agree that for this particular example a workaround is trivial and this module is probably not the best way to go, but I think the general idea of the module is great and can be used in non-trivial ways. And it might be one way to go for the original poster's problem, though (from my limited understanding of Class::Mulitmethods), he would have to do something more different than just passing in a simple scalar string with two different values, he would have to instead have different argument types or different numbers of arguments (Class::Multimethods doesn't seem to be able to dispatch based on the value of scalar args, just their type).
        I would very much like to see a case in Perl where the exact same function name has to be used for two completely different functions within the same object. In fact, I put this up as a friendly challenge, runrig. Actually, it's open to anyone who cares to try. :-)

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

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2021-05-10 18:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (106 votes). Check out past polls.

    Notices?