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

I have the following working code (truncated from original):
sub sub_name{ my ($self, %att) = @_; # $att{METHOD} or die "ERROR: Method not specified"; my $url = $self->{URL}; my $methodref = $self->{UA}->can ($att{METHOD}) or die "ERROR: No such METHOD: $att{METHOD}"; $self->{RESPONSE} = $methodref->( $self->{UA}, $url , ($att{VALUE}? ('Content' => to_json( +$att{VALUE})) : ()) ); ... }
where the UA attribute points to an LWP::UserAgent object.

I feel that the "$methodref->( $self->{UA}.. " syntax is a little ugly/unnatural, and there "should" be a more OO style syntax to achieve this. Any thoughts ?

Update:Formatted code.

        Software efficiency halves every 18 months, thus compensating for Moore's Law.

Replies are listed 'Best First'.
Re: Better syntax for dynamic method on internal object ?
by choroba (Cardinal) on Sep 22, 2015 at 19:51 UTC
    Do you mean
    $self->{RESPONSE} = $self->{UA}->$methodref( $url, $att{VALUE} ? (Content => + to_json($att{VALUE})) : (), );
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      No - I did not mean that.

      Your code would require a method NAME, not a subref, which is what I get from "can".

      My query was about how to call the subref in an OO-esque way.

              Software efficiency halves every 18 months, thus compensating for Moore's Law.

        It works with a sub ref returned from can for me:
        #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { package My::Url; sub new { my $class = shift; bless {@_}, $class } sub url { my ($self, $node_id) = @_; $self->{url} . '?node_id=' . $node_id } } my $o = 'My::Url'->new(url => 'http://www.perlmonks.org/'); my $methodname = 'url'; my $methodref = $o->can($methodname); say $o->$methodref(1142751);

        But even if it didn't, you know the name, right? You used it as the argument to can.

        Update: It's documented.

        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Better syntax for dynamic method on internal object ?
by dave_the_m (Monsignor) on Sep 22, 2015 at 21:50 UTC
    Note also that as long as you don't mind perl dying on your behalf when a method can't be found, you can skip the can():
    my $method = $att{METHOD}; $self->{RESPONSE} = $self->{UA}->$method($url, ....);

    Dave.

      Yes - I suppose I could 'eval' that, and try to create more friendly dying words.

      Perhaps even pre-verify the method name against a valid set - which are hopefully visible via the UA package namespace.

      Hmm - ok - more to munge on. Thanks for the suggestion.

              Software efficiency halves every 18 months, thus compensating for Moore's Law.

Re: Better syntax for dynamic method on internal object ?
by Your Mother (Archbishop) on Sep 23, 2015 at 02:18 UTC

    How about this? :P Time for terse overkill!

    sub do_something_with_a_uri { my $self = shift; my $uri = shift || die "uri is required"; my $method = $self->method; # You have to work out how to keep the JSON/Env stuff. $self->$method($uri); }

    And here’s the full working demo code–

        Oh… say… I always assumed title was a Mech provided method. I did not know it was in the underlying LWP stuff. I knew it existed but left it out of the example because of that. Good call-out. :P

      Thanks for that extravaganza.

      I was trying to keep dependencies to a minimum - this needs to run on a back-level perl (<= 5.8 vintage), in a distributed set of nodes that probably will not have moose.

      Thanks for the entertainment.

              Software efficiency halves every 18 months, thus compensating for Moore's Law.

        Sure, sure. Moo is not Moose and the usual even you can use the CPAN style rebukes apply. :P Not that I was intending that code to be serious. I do think the code you posted could be organized in a better way. The Moo style points to it but you know the code base so you’ll have to judge what measure is reasonable to apply.

A reply falls below the community's threshold of quality. You may see it by logging in.