I say: just put the my @f outside, as you've done in your last code block. All the other solutions I've seen so far are much uglier. Here's my contribution to the ugly solution set (with Test::More test framework, so you can see the one tye has up right now—but since fixed—doesn't actually work).

use strict; use warnings; use Test::More; my @tests = ( { a1 => [ 23 ], # 1 a2 => [ 42 ], call1 => 1, call2 => 0, want => 23, }, { a1 => [ 0 ], # 2 a2 => [ 42 ], call1 => 1, call2 => 0, want => 0, }, { a1 => [], # 3 a2 => [ 42 ], call1 => 1, call2 => 1, want => 42, }, { a1 => [ 23, 17 ], # 4 a2 => [ 42 ], call1 => 1, call2 => 1, want => 42, }, { a1 => [], # 5 a2 => [ 0 ], call1 => 1, call2 => 1, want => 0, }, { a1 => [ 23, 17 ], # 6 a2 => [ 0 ], call1 => 1, call2 => 1, want => 0, }, { a1 => [], # 7 a2 => [], call1 => 1, call2 => 1, want => undef, }, ); my @solutions = ( [ \&orig, 'original' ], [ \&ikegami, 'ikegami' ], [ \&tye, 'tye' ], [ \&kyle, 'kyle' ], [ \&anon, 'anon' ], ); plan 'tests' => 3 * scalar @solutions * scalar @tests; foreach my $s ( @solutions ) { try_one( @{ $s } ); } sub try_one { my ( $solution, $name ) = @_; my $tn = 1; foreach my $t ( @tests ) { my $code1_called = 0; my $code2_called = 0; my $code1 = sub { $code1_called = 1; return @{ $t->{a1} } }; my $code2 = sub { $code2_called = 1; return @{ $t->{a2} } }; is( $solution->( $code1, $code2 ), $t->{want}, "$name $tn" ); my $not; $not = $t->{call1} ? '' : ' not'; is( !!$code1_called, !!$t->{call1}, "$name did$not call code1" + ); $not = $t->{call1} ? '' : ' not'; is( !!$code2_called, !!$t->{call2}, "$name did$not call code2" + ); $tn++; } return; } sub orig { my ( $code1, $code2 ) = @_; my @f; if ((@f = $code1->()) == 1 || (@f = $code2->()) == 1) { return $f[0]; } return undef; } sub ikegami { my ( $code1, $code2 ) = @_; if ( sub { our @f; local *f = $_[0]; (@f = $code1->()) == 1 || (@f = $code2->()) == 1 }->(\my @f) ) { return $f[0]; } return undef; } sub tye { my ( $code1, $code2 ) = @_; if( my @f= do { my @g; 1 == ( @g= $code1->() ) || 1 == ( @g= $code +2->() ) ; @g } ) { return $f[0]; } return undef; } use List::Util qw( first ); sub kyle { my ( $code1, $code2 ) = @_; # fails the call/not call tests # if ( my @f = @{ (grep { @{$_}==1 } [$code1->()], [$code2->()] )[0 +]||[] } ) { if ( my @f = @{(first { @{$_=[$_->()]}==1 } $code1, $code2)[0]||[] +} ) { return $f[0]; } return undef; } sub anon { my ( $code1, $code2 ) = @_; if ( 1 == (my @f = $code1->() || $code2->()) ) { return $f[0]; } return undef; }

Update: Here's my one line:

use List::Util qw( first ); if ( my @f = @{(first { @{$_=[$_->()]}==1 } $code1, $code2)[0]||[]} )

Also, I added the anonymous reply (it fails several tests).

Update again: Changed tye's solution to what I think was originally intended.


In reply to Re: creating a variable in an if statement by kyle
in thread creating a variable in an if statement by Tanktalus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.