Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Rename a Moo constructor from "new" to "run"

by nysus (Vicar)
on Mar 27, 2019 at 23:42 UTC ( #1231768=perlquestion: print w/replies, xml ) Need Help??

nysus has asked for the wisdom of the Perl Monks concerning the following question:

I've got a Moo object with no public methods. It gets called once, does its thing and then isn't needed again. I want to rename the constructor to "run". How do I do this?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

  • Comment on Rename a Moo constructor from "new" to "run"

Replies are listed 'Best First'.
Re: Rename a Moo constructor from "new" to "run"
by Marshall (Abbot) on Mar 28, 2019 at 02:33 UTC
    I haven't used Moo in a real project yet. However, I am not sure that "rename" is what you need? That implies that "new" would no longer be valid. Maybe you just need a public method that does the same thing as new (i.e. create an alias to new)? Then in the code call "run" instead of calling "new"?

    sub run { my $class = shift; return $class->new( @_ ); }
    I don't see a problem with having two names for the method that creates an object, if $object->run(...) is more descriptive than $object->new(...) in the code. But could be that I'm missing some point?

    I am curious as to why this thing is an object instead of just a function call? There is considerable overhead in object oriented code. Why pay for something you don't need?

    Update: I replied to stevieb instead of to this post. But I figure my questions re: X-Y problem seem valid.

Re: Rename a Moo constructor from "new" to "run"
by stevieb (Abbot) on Mar 28, 2019 at 03:06 UTC
      I agree with that! The OP's whole question just seems odd to me.

      If there is no public I/F to an object, then what's the point of the object? If it is created by new() or run() or whatever and then very next line is the Perl version of "destroy", that code would warrant a #comment to explain that weirdness regardless of how the object was created in the first place - any new() vs run() would be explained also in that #comment. If this object is that simple, why need Moo in the first place? In traditional Perl OO, you can name the new() function whatever you want. Trying to make Moo do something that it doesn't want to do (like replace new() with run()) sounds like a bad idea. I would think either let Moo do it or do it yourself. I haven't used Moo in production, but I guess the idea is to automate and make easier the mechanics of object creation - why override that? If no object is needed in the first place, why have one?

        Maybe you want to have different implementations or want to replace some parts, while still having a defined sequence of calls.

        Personally, I've always run up to the limits of such frameworks, but I can well imagine an ETL task that is basically:

        package ETL::Import; sub run( $class, $input_file, $table ) { my $payload = $class->convert_to_csv( $input_file ); $class->cleanup( $payload ); $class->load( $payload, $input_file, $table ); $class->verify( $payload, $table ); };

        ... and then having

        package ETL::Import::CSV; ... package ETL::Import::Fixed; ...

        ... where each class only overrides (say) ->convert_to_csv and/or ->cleanup.

        As I said, I've almost always wanted to change just a tiny bit in the sequence of the call order, or maintain just one bit more information, so I prefer to have the logic of ->run in the main program instead of having it in some superclass. But if ->run is the result of a refactoring where it has proven flexible enough already, I can see how that could work out.

Re: Rename a Moo constructor from "new" to "run"
by ikegami (Pope) on Mar 31, 2019 at 07:19 UTC

    The constructor shouldn't be doing extended work. I'd go with the following:

    sub run { my ($self) = @_; ... do stuff with $self ... } # In user Class->new(...)->run();
    But, you could also go with either of the following:
    sub run { my $class = shift; my $obj = $class->new(@_); ... do stuff with $obj ... } # In user Class->run(...);
    sub run { my $class = shift; $class->new(@_)->_run(); } sub _run { my ($self) = @_; ... do stuff with $self ... } # In user Class->run(...);
Re: Rename a Moo constructor from "new" to "run"
by karlgoethebier (Monsignor) on Mar 28, 2019 at 23:15 UTC

    I guess: If you want a different implementation a role with a method modifier (around) might be a way to go. I’m not sure. Unfortunately i can‘t provide an example because i‘m about to set up my new machine. Regards, Karl


    Probably it might be interesting for you what i wrote a while ago to illustrate how to overwrite a constructor using inheritance using Class::Tiny. You may call it plugin, interface, fubar or what ever you like.

    I hope it is helpful and inspiring. And doesn’t look sub run { shift->SUPER::new(@_) } cool? 😎

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

        Thanks. But are you sure? Just because i still can't test it. I vaguely remember that it only worked with the SUPER::. Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1231768]
Approved by stevieb
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (10)
As of 2019-06-27 02:00 GMT
Find Nodes?
    Voting Booth?
    Is there a future for codeless software?

    Results (111 votes). Check out past polls.