Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: constants wont optimize

by Juerd (Abbot)
on Jul 09, 2011 at 23:54 UTC ( [id://913558]=note: print w/replies, xml ) Need Help??


in reply to constants wont optimize

Drop the "return" keyword:

juerd@lanova:~$ perl -MO=Deparse -e'BEGIN { eval "sub foo () { return +42; }" } print foo;' sub BEGIN { eval 'sub foo () { return 42; }'; } print foo; -e syntax OK juerd@lanova:~$ perl -MO=Deparse -e'BEGIN { eval "sub foo () { 42 }" } + print foo;' sub BEGIN { eval 'sub foo () { 42 }'; } print 42; -e syntax OK
Also, there's a better way than using eval. You can assign a code reference to a glob:
*glob = sub () { value };
juerd@lanova:~$ perl -MO=Deparse -e'BEGIN { *foo = sub () { 42 } } pri +nt foo;' sub BEGIN { *foo = sub () { 42 } ; } print 42; -e syntax OK

Juerd

Replies are listed 'Best First'.
Re^2: constants wont optimize
by patcat88 (Deacon) on Jul 10, 2011 at 17:06 UTC
    I think I found a solution, but I dont know why it works. The fix is to throw another BEGIN around the part that sets the constant. I would like to know why it works.
    C:\Documents and Settings\Owner\Desktop>cat consttest.pl & echo: & ech +o: & echo: & perl -MO=Deparse, consttest.pl & perl consttest.pl #!/usr/bin/perl -w #BEGIN { # package mod; # $VERSION = 1; # package main; #} BEGIN { BEGIN { if (scalar(%mod::) && $mod::VERSION ) { eval " sub haveMod () { 1; }" ;} else { eval "sub haveMod () { 0; }" ;} } sub checkMod () { if(haveMod()) {return "goodMod";} else {return "badMod";} } } print checkMod; BEGIN { $^W = 1; } sub BEGIN { sub BEGIN { sub checkMod () { do { return 'badMod' }; } } if (scalar %{'mod::'} and $mod::VERSION) { eval ' sub haveMod () { 1; }'; } else { eval 'sub haveMod () { 0; }'; } } print checkMod; consttest.pl syntax OK badMod C:\Documents and Settings\Owner\Desktop>
    Getting rid of the returns doesn't fix the problem, the return is always implied. Last statement of a subroutine is the return result in Perl.
    C:\Documents and Settings\Owner\Desktop>cat consttest.pl & echo: & ech +o: & echo: & perl -MO=Deparse, consttest.pl & perl consttest.pl #!/usr/bin/perl -w #BEGIN { # package mod; # $VERSION = 1; # package main; #} BEGIN { if (scalar(%mod::) && $mod::VERSION ) { eval " sub haveMod () { 1; }" ;} else { eval "sub haveMod () { 0; }" ;} sub checkMod () { if(haveMod()) {return "goodMod";} else {return "badMod";} } } print checkMod; BEGIN { $^W = 1; } sub BEGIN { if (scalar %{'mod::'} and $mod::VERSION) { eval ' sub haveMod () { 1; }'; } else { eval 'sub haveMod () { 0; }'; } } sub checkMod () { if (haveMod) { return 'goodMod'; } else { return 'badMod'; } } print checkMod; consttest.pl syntax OK badMod C:\Documents and Settings\Owner\Desktop>
      The fix is to throw another BEGIN around the part that sets the constant. I would like to know why it works.

      eval is a runtime operation. Sub declaration is a compile time operation. BEGIN does nothing to change that unless you use a BEGIN to perform the runtime eval before the compile time declaration occurs.

      All of the operations within a single BEGIN block occur, with respect to each other, in the order they would occur if not for the BEGIN block.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://913558]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-03-19 04:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found