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

Re^2: sub scope question

by papidave (Monk)
on Feb 07, 2008 at 13:17 UTC ( #666788=note: print w/ replies, xml ) Need Help??


in reply to Re: sub scope question
in thread sub scope question

I have to admit, I was entirely perplexed as well by this until I realized that my in Perl acts like an actual executed statement, not merely a declaration (like it would be, for example, in C). As a result, you get a new instance of $list_ref every time the function is called -- which is why it doesn't stay shared.

When I want to create a shared variable with long-term state like that (i.e., a C-style "static"), I put the applicable function definitions in a scope block with the my statement at the outer level -- e.g.:

#!/usr/bin/perl -w use strict; my @firstlist = qw(1 2 3 4 5); my @secondlist = qw(A B C D E); process_list(\@firstlist); process_list(\@secondlist); { my $list_ref; sub process_list { ($list_ref) = @_; sub get_list { return @$list_ref; } print_list(); } } sub print_list { foreach my $item (get_list()) { print "LIST ITEM: $item\n"; } }

which produces:

LIST ITEM: 1 LIST ITEM: 2 LIST ITEM: 3 LIST ITEM: 4 LIST ITEM: 5 LIST ITEM: A LIST ITEM: B LIST ITEM: C LIST ITEM: D LIST ITEM: E

as expected. Naturally, you could (per ikegami, should) also move the get_list() subroutine outside the scope of process_list() for clarity, since it doesn't really add value there -- but I left it as-is to minimize changes from your original program.

Update: Strengthened some wording in response to comments from ikegami on Perl internals


Comment on Re^2: sub scope question
Select or Download Code
Re^3: sub scope question
by ikegami (Pope) on Feb 07, 2008 at 13:38 UTC

    You say you get a new instance of $list_ref every time the function is called because my is not merely a declaration like in C. Yet you would get a new instance of local variables every time a function is called in C as well! Consider a re-entrant function, for example.

    In fact, as an optimization in Perl, you *don't* get a new instance of my variable every pass unless you do something that forces Perl to create a new variable. That's an implementation detail you shouldn't worry about, though.

    As for your suggestion to move my $list_ref, it seems to miss the point that nesting *named* functions has no benefit in Perl. Instead of trying to make the nested named function work, one should look at what one wants to achieve by nesting a named function and look for ways to meet that goal. (local *name = sub { ... }; is the likely answer.)

      ikegami,

      Thank you for the comments on my implementation details; I have improved my wording above. As regards the remainder of your response, I think we both agree that nesting named functions has no benefit in Perl; we differ only in how to resolve it.

      By going with an unnamed function assigned to a local var, you eliminate the "named" part; by moving $list_ref outside the function, you can then also move the named function to main scope, thereby eliminating the "nesting".

      In either case, I favor passing arguments into a subroutine over retention of state information in a closure or any kind of shared variable, because I find it easier to maintain -- but then, TMTOWTDI.

        Making a local variable variable into a semi-global one in order to use it to pass arguments to a function doesn't sound like the right approach to me. For starters, it breaks if the outer function is re-entrant and can break if the inner function is re-entrant, and that's when I normally use nested subs.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2015-07-04 21:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls