BEGIN { *basename = shortcutted { s!.*/!! for @_ }; } for( '/path/to/foo', '/some/path/to/bar' ) { print "Munging " . basename . "\n"; open my $fh, '<', $_ or die $!; # note how $_ still contains the full pathname # ... } #### sub shortcutted(&) { my $sub = shift; sub { my @byval; my $nondestructive = defined wantarray; $sub->( $nondestructive ? ( @byval = @_ ? @_ : $_ ) : ( @_ ? @_ : $_ ) ); return $nondestructive ? @byval[ 0 .. $#byval ] : (); }; } #### use Test::More; sub original() { 'original' } sub modified() { 'modified' } my $test = shortcutted { $_ = modified for @_ }; plan tests => my $num_tests; { local $_ = original; $test->(); is( $_, modified, 'in-place on $_' ); BEGIN { $num_tests += 1 } } { local $_ = original; my $res = $test->(); is( $_, original, 'nondestructive from $_' ); is( $res, modified, '...returned correctly' ); BEGIN { $num_tests += 2 } } { my $num = 10; my @original = ( original ) x $num; my @modified = ( modified ) x $num; $test->( my @data = @original ); is_deeply( \@data, \@modified, 'in-place on params' ); BEGIN { $num_tests += 1 } } { my $num = 10; my @original = ( original ) x $num; my @modified = ( modified ) x $num; my @res = $test->( my @data = @original ); is_deeply( \@data, \@original, 'non-destructive from params' ); is_deeply( \@res, \@modified, '...returned correctly' ); BEGIN { $num_tests += 2 } }