[Pdx-pm] the quest for return_if

Tom Phoenix rootbeer at redcat.com
Tue Jun 26 16:32:40 PDT 2007


On 6/26/07, benh <ben.hengst at gmail.com> wrote:

> Ideally I would love to do this:
>
> sub return_if {
>    my ($eval, $value) = @_;
>    $value = $eval if !defined($value);
>    {FROM_THE_POINT_WHERE_I_WAS_CALLED}->return $value if defined($eval);
> }

How would you use such a thing? Like this?

  &return_if( SOME_EXPR );

  &return_if( SOME_EXPR, EXPR_TO_RETURN );

I get your idea that the sub makes the calling sub return. (What does
it do if it wasn't called from a sub? Crash?)

I'm thinking you really want something like this:

  return(SOME_EXPR err ANOTHER);

Where err is the new err operator rumored to become available
somewhere around 5.10, but certainly by Perl 6. It returns its left
operand if that's defined, else its right operand.

But it's still not quite what you're looking for, is it? There's
probably some hocus pocus possible with a module to muck with Perl's
return stack, but I can't recommend that. But I think what you're
asking for is a new control structure, so it's a tall order.

Still, you might be able to do something. Although this trick feels
about as bad as using goto.

sub return_if {
  my($value) = shift;
  return unless defined $value;
  $value = shift if @_;  # uses second parameter, if given
  our $returnable = $value;  # set the return value
  last;  # "return" it after the calling loop block
}

sub extra_tricky {
  our $returnable = undef;
  {
    &return_if( SOME_EXPR );
    &return_if( ANOTHER_ONE );
  }
  ## last comes here ##
  return $returnable if $returnable;
  return 'default result';
}

I believe most recent releases of Perl can warn you against this. With
good reason.

Good luck with it!

--Tom Phoenix


More information about the Pdx-pm-list mailing list