Skip to content

Instantly share code, notes, and snippets.

@jest
Created May 24, 2011 19:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jest/989521 to your computer and use it in GitHub Desktop.
Save jest/989521 to your computer and use it in GitHub Desktop.
Lexical vars in a closure
#!/usr/bin/env perl
use warnings;
use strict;
{
my %hsh = map { ($_ => 1) } qw( some costy hashmap here );
sub has {
return $hsh{$_[0]};
}
};
print has('costy'), "\n";
print has('hash'), "\n";
@worr
Copy link

worr commented May 24, 2011

Am I just totally mistaken, or does the sub only exist with in that block? I threw a var outside of the closure, than assigned it a reference to my internal sub so I could see it outside of that block.

Or do subs always have global scope and I'm just an idiot?

@jest
Copy link
Author

jest commented May 24, 2011

I don't know you in person, so I can't comment on that 'idiot stuff' ;)

sub's are not lexical, but package-scope. By chance, the above gist is identical to the docs' one: http://perldoc.perl.org/perlsub.html#Persistent-variables-with-closures

@worr
Copy link

worr commented May 25, 2011

Ha, well thanks for the heads up. I don't know why I totally thought subs had lexical scope. I guess my solution would have worked, albeit it was far more work than needed to be done.

@jest
Copy link
Author

jest commented May 25, 2011

Subs are "global", i.e. kept in package symbol table, which you can manipulate during runtime, e.g.

sub a_gen {
    return \&a;
}

sub a { 'outer' };

say a, a_gen->(); # says outerouter

{
    no warnings 'redefine';                                                     
    local *a = sub { 'inner' };

    say a(), a_gen->(); # says innerinner
}

say a, a_gen->(); # says outerouter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment