in reply to Re^3: Unable to declare local variable with "use strict".
in thread Unable to declare local variable with "use strict".

If possible I would like to use variable that is accessible bye ref_test2 without passing in as argument.

sub ref_test1 { local our $type="connect"; print "Here in ref_test1.\n"; ref_test2(); } sub ref_test2 { our $type; print "Type: $type\n"; print "Here in ref_test2\n"; }

Replies are listed 'Best First'.
Re^5: Unable to declare local variable with "use strict".
by rovf (Priest) on Mar 29, 2010 at 15:58 UTC
    If possible I would like to use variable that is accessible bye ref_test2 without passing in as argument.
    So you mean you want to share a variable between functions? The solution here is to use a lexical within a closure:

    { # closure starts here my $shared_variable; sub ref_test1 { ... } sub ref_test2 { ... } }

    -- 
    Ronald Fischer <ynnor@mm.st>
      Generally, when people speak of a 'closure' in Perl, people mean a specific kind of subroutine, not a block, as your comment seems to indicate.

      Closures are typically unnamed subroutines, holding a reference to their private instance of a variable (although such a variable may be shared between more than one subroutine). In your case, the subroutines are named, and there will only be once instance of $shared_variable.

      Note also that your technique doesn't scale very well. Suppose you have subroutines sub1, sub2, sub3 and sub4. sub1 and sub2 want to share a variable $var1, sub2 and sub3 want to share a variable $var2, sub3 and sub4 want to share variable $var3, and sub4 and sub1 want to share $var4. In effect, you end up with all variables visible to all subroutines. An extra block doesn't really buy you much.

        Generally, when people speak of a 'closure' in Perl, people mean a specific kind of subroutine, not a block, as your comment seems to indicate.

        I wouldn't say it's generally not the block. I would say it's never the block. Besides that, I agree. The subs are closures, not the scope in which the variables reside.

        Closures are typically unnamed subroutines

        So?

        The code featured functions that captures a variable beyond it's normal scope. They are very much closures.

        It's really not that atypical either. It happens whenever you have module-level ("global") lexicals. The lexicals would normally fall out of scope when the module finished executing (i.e. before require returns), but they survive thanks to the methods that capture them.

        The only difference between named and unnamed subs is when the capture occurs. Named subs are instantiated at compile-time, so they capture at compile-time. Unnamed subs are instantiated at run-time, so they capture at run-time.

        [ Please ignore this post and read Re^7: Unable to declare local variable with "use strict". instead ]

        Are you saying he shouldn't call it a closure because (you say) it's not the general or typical example?

        The code featured functions that captures a variable beyond it's normal scope. They are very much closures.

        It's really not that atypical either. It happens whenever you have module-level lexicals. The lexicals would normally fall out of scope when the module finished executing when it's loaded, but they survive thanks to the methods that capture them.

        The only difference between named and unnamed subs is when the capture occurs. Named subs are instantiated at compile-time, so they capture at compile-time. Unnamed subs are instantiated at run-time, so they capture at run-time.

        JavaFan wrote:
        Generally, when people speak of a 'closure' in Perl, people mean a specific kind of subroutine, not a block, as your comment seems to indicate.

        I disagree. Any block that creates scoped variables is a closure in my book.

        Note also that your technique doesn't scale very well. Suppose you have subroutines sub1, sub2, sub3 and sub4. sub1 and sub2 want to share a variable $var1, sub2 and sub3 want to share a variable $var2, sub3 and sub4 want to share variable $var3, and sub4 and sub1 want to share $var4. In effect, you end up with all variables visible to all subroutines. An extra block doesn't really buy you much.

        While you are absolutely right, who cares? Are you saying that everyone who creates a class has to build a potentially exhaustive set of classes and subclasses so that no one can see things that don't belong to them?

        Information hiding is a wonderful thing, but there is no need to go overboard with it. If you've got it down to where just a handful of localised subroutines (same closure) can get to the protected data, then you've done well enough.

        - doug