http://www.perlmonks.org?node_id=978412

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

Dear Monks,

I come here with a simple problem: I need to add a timeout to a method call, and now think about the best way how to 'say' it. Well, I don't want to use named parameters for such a simple task.

Here the original call without timeout:

my $success = $deployer->extend_order_lease( $order, $end_date );

Well, I wrote a little sub which deals with the timeout, and called it like the following:

Number 1:

my $success = $self->do_method_with_timeout( $timeout, $deployer => extend_order_lease => ( $order, $end_date ) );

The => looks a little bit like the -> from the original call, but there are no pairs.

Number 2:

my $success = $self->do_method_with_timeout( $timeout, $deployer, 'extend_order_lease', $order, $end_date );

But there you don't see what belongs together...

Number 3:

my $success = $self->do_sub_with_timeout( sub { return $deployer->extend_order_lease( $order, $end_date ); }, $timeout, );

But the longer I look at those ways, the less I like them...

Please, could you help me and tell me how you would write it?

Best regards,
perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Replies are listed 'Best First'.
Re: Style - how to give class method call as parameter
by Corion (Patriarch) on Jun 26, 2012 at 13:47 UTC

    Personally, I like number three best, but as an alternative, you can wrap number three in some syntactic sugar:

    sub transaction(&$$) { my ($cb, $self,$timeout) = @_; $self->do_sub_with_timeout( $cb, $timeout ); }; transaction { $deployer->extend_order_lease( $order, $end_date ); } $self, $timeout;

    Unfortunately, the & prototype must come as the first argument. I'm also not convinced that this style is less confusing/more readable than the other.

      Well, I reply to Corion's posting although it becomes a general reply to all who replied ;-)

      Thank you very much for your replies. I hoped for a beautiful way to write this, but I will use version 3 since it looks less ugly than the other two ways.

      Adding a timeout-parameter to extend_order_lease would be best. But I don't dare to change the external framework or Boldra would look at me with very sad eyes the whole day long ;-)

      The synthetic sugar with the prototype looks nice, but in my case I don't want to use it. I put the methods do_sub_with_timeout or do_method_with_timeout into a Moose role so we can be use them everywhere in our framework (in the moment in about 4 different classes), and so I want them to be methods and not subs for not to need import subs into a foreign namespace. (And methods ignore prototypes anyway.)

      Have a nice evening

      Best regards,
      perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Re: Style - how to give class method call as parameter
by dsheroh (Monsignor) on Jun 26, 2012 at 14:31 UTC
    Well, I don't want to use named parameters for such a simple task.
    Why not? It's not like they're difficult to implement/use in Perl. You could even use a mix of positional (required) parameters and named (optional) parameters:
    my $success = $deployer->extend_order_lease( $order, $end_date, timeou +t => $timeout );
    There's also the option of making it an optional positional parameter, but that tends to be a bad idea, due to things getting messy if you add more optional parameters down the road.
    my $success = $deployer->extend_order_lease( $order, $end_date[, $time +out] );

      Hello dsheroh,

      I don't want to use named parameters for this because it is just a simple call. I usually don't like mixed parameters, and with names for everything, I need to write something like:

      my $success = $self->do_method_with_timeout( timeout => $timeout, object_or_class => $deployer method => 'extend_order_lease', args => [ $order, $end_date ], );

      In my eyes, too much code for a simple thing

      Best regards,
      perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Re: Style - how to give class method call as parameter
by Athanasius (Archbishop) on Jun 26, 2012 at 13:40 UTC

    Number 3a:

    my $success = $self->do_sub_with_timeout( $deployer->extend_order_leas +e( $order, $end_date ), $timeout );

    But there’s nothing wrong with Number 1.

    Update: Seems I missed the point of the question. Thanks to Boldra and choroba for pointing out that my ‘solution’ preempts the timeout.

    Athanasius <°(((><contra mundum

      That's not going to work, extend_order_lease will be executed before do_sub_with_timeout gets called, so there'll be no chance for it to interrupt.

      OP: How much code is in do_sub_with_timeout? Since the subroutine/method call is making it less readable, maybe there's no benefit in putting it in a subroutine? Maybe what you really want is a sub like handle_timeout which gets called if the timeout is exceeded.

      That's not the same. You are calling the method, not passing a reference to it.
Re: Style - how to give class method call as parameter
by NetWallah (Canon) on Jun 27, 2012 at 03:11 UTC
    How about method-chaining - you can Chain the timeout method when you need it :
    use strict; use warnings; {package This; sub new{ my ($class, %att )=@_; return bless {%att}, $class; } sub with_timeout{ my ($self, $timeout) = @_; $timeout or die "Timeout not specified"; return bless {%$self, TIMEOUT=>$timeout},__PACKAGE__; } sub do_work{ my ($self) = @_; for my $k(sort keys %$self){ print "$k \t=>" . ( $self->{$k}||"Undef*") . "\n"; } } 1; } my $t = This::->new (CANDY=>'Mint'); print "-- First call - no TIME--\n"; $t->do_work(); print "-- adding time--\n"; $t->with_timeout(10)->do_work(); print "-- this should not have it--\n"; $t->do_work();

                 I hope life isn't a big joke, because I don't get it.
                       -SNL

Re: Style - how to give class method call as parameter
by Schnufftlapper (Initiate) on Jun 26, 2012 at 13:30 UTC
    I think Number 3 is the most readable.