Hi Xiaolan!

On Sunday 24 Jan 2010 05:37:49 Xiao Lan (小兰) wrote:
> Hi,
> 
> what's the difference between do a block and eval a block?
> 
> sub test {
>     my $bl = shift;
>     eval $bl;
>     # do $bl;
> }
> 
> test { print "hello\n" };

Well, if I run:

<<<<<<<<<<<<<<<<
#!/usr/bin/perl

use strict;
use warnings;

sub test {
    my $bl = shift;
    eval $bl;
    # do $bl;
}

test { print "hello\n" };
>>>>>>>>>>>>>>>>

I'm getting:

<<<<<<
$ perl Test.pl
hello
Odd number of elements in anonymous hash at Test.pl line 12.
>>>>>>

This is a hint that the "print" gets evaluated at the line of the test, and 
then perl thinks it is an anonymous hash-ref. If you are more explicit and use 
a << sub { ... } >>, like so:

<<<<<
#!/usr/bin/perl

use strict;
use warnings;

sub test {
    my $bl = shift;
    eval $bl;
    # do $bl;
}

test(sub { print "hello\n" });
>>>>>

Then it prints nothing, because the eval tries to evaluate the sub {...} 
reference as a string. (And do $bl will try to read a file and process it for 
code). What you really want is a:

<<<<
#!/usr/bin/perl

use strict;
use warnings;

sub test {
    my $bl = shift;
    print "Before\n";
    eval { $bl->() };
    print "After\n";
    # do $bl;
}

test(sub { print "hello\n" });
>>>>

Now, in this case, eval { ... } and do { ... } will work the same. But there 
would be changes:

1. If you throw an exception, then eval will catch it and set $@ to it. If no 
exception was thrown, it will set "$@" to the empty string. Also look at 
Object-Oriented exceptions:

http://www.shlomifish.org/lecture/Perl/Newbies/lecture4/exceptions/

2. If you do something funky like << do { ... } while (COND()) >> then Perl 
has some magic to execute the contents of the do { ... } once before 
evaluating the COND() (as opposed to << while (COND()) { BODY } >> ).

--------------

So if you want to do something like << my $var = RESULT_OF_BLOCK; >> use do { 
... } and if you want to trap an exception use eval { ... } (and check $@ 
afterwards).

Regards,

        Shlomi Fish

> 
> from the code, I see both do and eval work the same.
> 
> Thanks.

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
http://www.shlomifish.org/humour/ways_to_do_it.html

Deletionists delete Wikipedia articles that they consider lame.
Chuck Norris deletes deletionists whom he considers lame.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to