Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Can / Do BEGIN blocks return their evaluated content?

by dynamo (Chaplain)
on Dec 21, 2007 at 18:20 UTC ( [id://658491] : perlquestion . print w/replies, xml ) Need Help??

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

Fellow Monks,

I've thinking about the BEGIN block today - and whether or not it returns it's contents. I did a quick experiment that doesn't really conclude anything except that perl doesn't want to play along.

Here is what I'm simulating:
#!/usr/bin/perl sleep 4; BEGIN { $anon = time } print "timespan: " . (time - $anon); # shows 4
And here's how I think it should be able to work:
#!/usr/bin/perl sleep 4; print "timespan: " . (time - BEGIN{time}); # should show 4
But I get this error:
Can't call method "BEGIN" without a package or object reference at timemachine.pl line 4.

Is there a way to make it do what I want? What exactly is it complaining about there? I tried doing it inside a package, but alas. It was to no avail.

Your thoughts would be appreciated.

Replies are listed 'Best First'.
Re: Can / Do BEGIN blocks return their evaluated content?
by Fletch (Bishop) on Dec 21, 2007 at 18:35 UTC

    You can't just stick a named BLOCK there in the middle of an expression and expect it to work. If you use B::Deparse you'll see it's being parsed as trying to call the method BEGIN on the return value of a block with just time in it.

    sleep(4); print(('timespan: ' . (time - do { time }->BEGIN)));

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

Re: Can / Do BEGIN blocks return their evaluated content?
by Roy Johnson (Monsignor) on Dec 21, 2007 at 18:49 UTC
    Neither BEGIN nor INIT blocks evaluate to anything. The way to do what you want is probably to involve a do block and a variable:
    sleep 4; print "timespan: " . (time - do { my $btime; BEGIN {$btime=time} $btime }); # should show 4

    Caution: Contents may have been coded under pressure.
Re: Can / Do BEGIN blocks return their evaluated content?
by shmem (Chancellor) on Dec 22, 2007 at 00:17 UTC
    BEGIN blocks are compiled and executed during the compilation of the program text in which they appear. Since the containing program text is just compiled, an assignment of a BEGIN block's return value cannot take place: that would be runtime. That's why use (compile time) doesn't return anything, while require (runtime) does.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Can / Do BEGIN blocks return their evaluated content?
by jhourcle (Prior) on Dec 21, 2007 at 20:57 UTC

    You may wish to explain _why_ you want it to work. If you're just interested in the time that the program started, use $^T (or $BASETIME, if you're using English).

      Why? I have no legitimate reason - it just seemed to be a good idea, and a weird programming paradigm if allowed.
Re: Can / Do BEGIN blocks return their evaluated content?
by ikegami (Patriarch) on Dec 22, 2007 at 06:14 UTC
    Interesting, but it would need a new syntax that doesn't involve BEGIN. BEGIN { } is short for sub BEGIN { }, and while you can define subroutines within an expressions, they must be unnamed.