Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: MOPT-04 - identification, part 2

by Courage (Parson)
on Jan 07, 2003 at 12:53 UTC ( #224951=note: print w/ replies, xml ) Need Help??


in reply to MOPT-04 - identification, part 2

I have a correction to your first part of a message
Perl's function bindings are statically scoped, not dynamically scoped, so we can't bind the name to a new entity in a different evaluation context. If we want to play with dynamically scoped entities in Perl, we have to stick to local variables.

Actually you can redefine subroutine by using eval "sub func {'...'}" and better yet is just to use anonymous subroutines and use ordinary variables to switch between different ones:

my $func = sub { return "value"; }; $func->(); $func = sub { return "another value"; }; $func->();

Courage, the Cowardly Dog


Comment on Re: MOPT-04 - identification, part 2
Select or Download Code
Re2: MOPT-04 - identification, part 2
by mstone (Deacon) on Jan 08, 2003 at 01:52 UTC
    • Actually you can redefine subroutine by using eval "sub func {'...'}"

    That would create a new function at runtime, but it wouldn't follow the rules of dynamic scoping (see MOPT-03 for details).

    As you've used it, the eval() just binds a new function to the name 'func'. To be dynamic, the new version of func() would have to be restricted to the evaluation context of the function that defined it:

    $VAR = "old VAR"; sub func {return ("old func()")} sub show {printf "VAR='%s', func()='%s'\n", $VAR, func()} sub redefine { eval 'sub func {return ("new func()")}'; local ($VAR) = "new VAR"; show(); } show(); redefine(); show();

    returns:

    VAR='old VAR', func()='old func()' VAR='new VAR', func()='new func()' VAR='old VAR', func()='new func()'

    which shows the difference between redefining a globally-scoped function and re-binding a dynamically-scoped variable.

    • and better yet is just to use anonymous subroutines and use ordinary variables to switch between different ones:

    Yes, that would work:

    $VAR = "old VAR"; $FUNC = sub {return ("old func()")}; sub show {printf "VAR='%s', func()='%s'\n", $VAR, &$FUNC()} sub redefine { local ($FUNC) = sub {return ("new func()")}; local ($VAR) = "new VAR"; show(); } show(); redefine(); show();

    returns:

    VAR='old VAR', func()='old func()' VAR='new VAR', func()='new func()' VAR='old VAR', func()='old func()'

    which does the right thing. But to get the effect of a dynamically-scoped function, you have to use a dynamically scoped (aka: local) variable, and I did say that in the original article.

    HOWEVER.. check out the next reply to see how I was, in fact, wrong.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (10)
As of 2014-12-26 08:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (168 votes), past polls