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

Hi all,

here is what did:

The role:

package Utils; use URI; use List::MoreUtils qw(uniq); use Types::Standard qw(InstanceOf); use Moo::Role; requires qw(list monks); sub my_uniq { my $self = shift; my @result = uniq @{ $self->list }; wantarray ? @result : scalar @result; } has 'uri' => ( is => 'lazy', isa => InstanceOf ['URI'], default => sub { my $self = shift; URI->new( $self->monks ) }, handles => [qw(host)], ); 1; __END__

The class:

package Karl; use Types::Standard qw(ArrayRef Str); use Moo; has list => ( is => 'lazy', isa => ArrayRef ); has monks => ( is => 'lazy', isa => Str ); with qw(Utils); 1; __END__

And the script:

#!/usr/bin/env perl use strict; use warnings; use feature qw(say); use Data::Dump; use Karl; my $monks = qq(http://www.perlmonks.org); my $list = [qw(cuke cuke)]; my $nose = Karl->new( list => $list, monks => $monks ); dd $nose; my $uniq = $nose->my_uniq; say $uniq; my @uniq = $nose->my_uniq; say for @uniq; say $nose->host; __END__

This works as expected and i hope that it is good practice. OK, i'm a bit unsure about this :-(

But i wonder how to handle the call to uniq like the call to host.

I would like to say $nose->uniq, instead of $nose->my_uniq.

In other words: how can i proxy (or delegate) a sub from a non OO module?

I must admit that i'm a bit confused for the moment.

Best regards and thank you very much for any hint, Karl

«The Crux of the Biscuit is the Apostrophe»

Replies are listed 'Best First'.
Re: Moo From Hell #1: How to proxy a sub from a non OO module
by AnomalousMonk (Archbishop) on Aug 02, 2015 at 17:16 UTC

    I can't test this ATM, it's just a guess, but why not something like:

    package Utils; ...; use List::MoreUtils (); # note empty optional import list ...; ...; sub uniq { my $self = shift; # fully qualify List::MoreUtils function my @result = List::MoreUtils::uniq @{ $self->list }; wantarray ? @result : scalar @result; } ... 1; # And the script: ... use Karl; ... ... my $uniq = $nose->uniq; ...

    Update: (Update: And a bit OT:) Does Moo interfere with the propagation of context in some way I'm not aware of? If not, the return statement of  my_uniq() in the OPed code
        wantarray ? @result : scalar @result;
    would seem to return exactly what would be returned anyway in list or scalar context by just returning an array, i.e., the same as a
        return @result;
    statement. It makes no particular difference, but I was just curious.


    Give a man a fish:  <%-(-(-(-<

      "...why not something like..."

      Yes sure. I tried i already. Because of...

      karls-mac-mini:MyMoo karl$ ./run.pl Prototype mismatch: sub Utils::uniq (@) vs none at Utils.pm line 20. Compilation failed in require at /Users/karl/perl5/perlbrew/perls/perl +-5.20.0threads/lib/site_perl/5.20.0/Module/Runtime.pm line 317. Compilation failed in require at ./run.pl line 7. BEGIN failed--compilation aborted at ./run.pl line 7.

      ...what i don't understand (for the moment). OK, I should have mentioned it...sorry.

      Best regards and thanks for advice, Karl

      «The Crux of the Biscuit is the Apostrophe»

      "...Does Moo interfere with the propagation of context in some way..."

      I guess it doesn't. Same behavior without wantarray.

      Regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

Re: Moo From Hell #1: How to proxy a sub from a non OO module [SOLVED]
by Monk::Thomas (Friar) on Aug 03, 2015 at 08:58 UTC

    (This is unrelated to your actual question / problem.)

    Why do you use wantarray?

    sub my_uniq { my $self = shift; my @result = uniq @{ $self->list }; wantarray ? @result : scalar @result; }

    Why don't you simply write

    sub my_uniq { my $self = shift; return uniq @{ $self->list }; }

    My guess is it's a performance optimization since it reimplements already existing behaviour. Have you benchmarked it?

    My personal opinion - feel free to ignore it.

    As far as I can see the method my_uniq is simply a convenience function to make it easier to work with the array reference stored in the field 'list'. I would design the class differently and not provide any direct access to the field 'list' at all. Instead provide an accessor which returns the list as an array and drop the convenience function 'my_uniq'.

    # class method sub get_list { my $self = shift; return @{ $self->list() }; }
    # client code - variant a # (client wants values and count) my @uniq_list = uniq $obj->get_list(); my $uniq_count = scalar @uniq_list; # client code - variant b # (client just wants the count) my $uniq_count = scalar uniq $obj->get_list();

    Main reason: If the user wants to do something else with the list (e.g. reverse) then I don't need to reimplement these functions too.

      This is unrelated to your actual question / problem.

      But this reply bears upon the question of organization or factoring of code, which is closely related to the OPed question. ++ from me.

      My personal opinion - feel free to ignore it.

      The section advising use of a list getter for member data so that normal list processing functions can be used on the data makes me wish I could ++ again. Ignore this advice if you will, but you do so at your own peril!


      Give a man a fish:  <%-(-(-(-<