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

Hi together,

I stumbled across this problem today, while looking at some code using Test::Simple. The following test always passes, even if the string doesn't match:

ok(sub{$str =~ /abc/}, "string matches");

Now I can easily rewrite this test to:

ok($str =~ /abc/, "string matches");
Now it will only pass in case the string really matches. Problem solved.

But the question I'm really asking myself here is why did it pass in the first time? I wrote this simple example program:

#!/usr/bin/perl use strict; use warnings; (sub {my $str = "aaa"; $str =~ m/abc/}) ? print "sub ok\n" : print "su +b fail\n"; get_return() ? print "return ok\n" : print "return fail\n"; sub get_return { my $str = "aaa"; $str =~ m/abc/; }
The output is:
sub ok return fail
Can someone help me understand why the result of the anonymous (?) sub is true and the result of the regular sub is false?

Replies are listed 'Best First'.
Re: Return value of a sub
by Fletch (Bishop) on Jul 07, 2009 at 19:11 UTC

    The construct sub BLOCK creates an anonymous sub (aka a code reference or "coderef"); it doesn't call the created sub in any fashion (you'd need to do something along the lines of (sub {$str =~ /abc/})->() using your example). As the coderef is always a logically true value the test always passes.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Thanks a lot (also to FunkyMonk). This perfectly answers my question. I think my confusion arose from the fact that the lives_ok test of Test::Exception also accepts these type of test constructs (copy & pasted directly from the CPAN site):
      lives_ok( sub { $file = read_file('test.txt') }, 'file read' );
        I think my confusion arose from the fact that the lives_ok test of Test::Exception also accepts these type of test constructs.
        Now that that's cleared up, you might be interested why Test::Exception requires subroutine references: it wouldn't be possible to catch the exception thrown otherwise (well, actually you could hack around that, but it wouldn't be as reliable and it would probably mess up the code flow). Inside the Test::Exception code there's probably something like eval { $coderef->() } # now do something with $@.

        All of the Test::Exception test functions also allow you to leave off the "sub", and instead just use curly braces, but that's really just a convenience made possible by the often misunderstood prototype facility; you're still passing a subroutine reference as the first argument.

Re: Return value of a sub
by FunkyMonk (Bishop) on Jul 07, 2009 at 19:14 UTC
    You're defining an anonymous sub, but not calling it. Try
    (sub {my $str = "aaa"; $str =~ m/abc/})->() ? print "sub ok\n" : print + "sub fail\n"; #sub fail
      Or even, with fewer parens:
      >perl -wMstrict -le "sub { print $_[0] }->('hi')" hi