Cool/useful short examples of Perl?

David Matthewman david at matthewman.org
Thu Jun 9 14:22:58 BST 2011


On 9 Jun 2011, at 12:10, David Landgren wrote:

> On 08/06/2011 15:00, David Matthewman wrote:
>> 
>> On 8 Jun 2011, at 13:17, Tom Hukins wrote:
>> 
>>> On Wed, Jun 08, 2011 at 02:00:41PM +0200, Abigail wrote:
>>>> I'd rather go for sacking people that don't know the difference
>>>> between
>>>> 
>>>>    if (something) { ... }
>>>> 
>>>> and
>>>> 
>>>>    unless (!something) { ... }
>>> 
> 
> [...]
> 
>> Their side effects are different. There may be a simpler way to demonstrate this, but for instance:
> 
> I still don't get it. Abigail wasn't talking about !!. Your code seemed to be more to the point, and so I fleshed it out. Consider:

OK. Backing up a little, this is really an exercise in 'always explicitly return from a subroutine if you're *ever* going to care what the return value is.'

If you don't explicitly return from a subroutine in Perl, it returns the value of the last statement executed. Now:

    if ($value) ...

and:

    unless (!$value) ...

are not executing the same statement, and a subroutine returning immediately after each test will consequently not return the same thing.

Bearing that in mind:

#! /usr/bin/env perl

print "unless ( !1 ): ";
print use_unless(1) . "\n";
print "    if (  1 ): ";
print use_if(1) . "\n";
print "unless ( !0 ): ";
print use_unless(0) . "\n";
print "    if (  0 ): ";
print use_if(0) . "\n";

sub use_unless {
    my $value = shift;
    my $state = 'False!';
    unless ( !$value ) {
        $state = 'True!';
    }
}

sub use_if {
    my $value = shift;
    my $state = 'False!';
    if ( $value ) {
        $state = 'True!';
    }
}

#### End of code ####

This prints out:

unless ( !1 ): True!
    if (  1 ): True!
unless ( !0 ): 1
    if (  0 ): 0

When the subroutines are called with a true value, the 'if' or 'unless' test succeeds, the inner block is run, and the subroutine returns 'True!' because that was the result of the last statement it executed. If called with a false value, the test fails, the inner block isn't run, and the subroutine returns the value of the test expression, which is different in the two cases. (The case where the subroutines are called with false values are the interesting ones from the point of view of the discussion, but I included the ones where they were called with true values in the hope that it would show what was going on better.)

And now I'm wondering whether all this is either blindingly obvious to everyone else on the list and you can't believe I'm explaining something so basic, or abstruse in the extreme and you can't believe I'm noodling about such an unlikely edge case. Or both. ;-)

-- 
David Matthewman


More information about the london.pm mailing list