Reputation: 2102
I was wondering if it's possible to declare a global variable within a subroutine in Perl so that I can use that variable in a hooked void function, but limiting the damaging effects of the global by having it declared in a subroutine.
So the subroutine uses XML::Parser
to collect the IDs of a bunch of elements, in a manner similar to:
sub getRecipeIDs {
my $recipe = shift;
my @elements = ();
my $parser = new XML::Parser(Style => 'Tree',
Handlers => {
Start => sub {
my ($expat, $element, %attrs) = @_;
if ($element eq 'recipe') {
push @elements, $attrs{id};
}
}});
$parser->parse($recipe);
return @elements;
}
I'm also using strict
in my script.
So I want to declare @elements
in such a way that it is local to getRecipeIDs
but is visible to the anonymous subroutine.
Thanks for your time, any help is greatly appreciated.
Upvotes: 2
Views: 916
Reputation: 126772
Your code should work fine as it stands
Despite the depth of the anonymous subroutine, its scope includes the lexical array @elements
and it can access it freely
Furthermore the subroutine counts as a reference to the array, so it will not be garbage collected when it goes out of scope at the end of the call to getRecipeIDs
Upvotes: 3
Reputation:
It should already work the way in which you've written your example. What you're doing with "my $func = sub { ... }
" is you create a closure which has access to the enclosing scope's variables -- in this case @elements
.
Upvotes: 6
Reputation: 5555
my
is fine. Lexical variables are visible in nested scopes, such as anonymous subroutines.
Your code should therefore work as-is.
Upvotes: 3