How could I share a variable declared in one subroutine to another subroutine, that's called inside it, without having global variable names collisions, or declaring the variable outside the mother caller subroutine, or using any subroutine parameters?
in other words: How could I call a variable defined in a subroutine from a sub-called subroutine?
More explanation: (in case the previous single-line question wasn't descriptive enough)
Please note that you don't need to read to the end to understand my question. Stop reading if you've got what I'm asking about to save your time.
Let's say I have subroutine1
and subroutine2
as so:
subroutine1 ();
sub subroutine1 {
my $word1='hello';
subroutine2();
}
sub subroutine2 {
print $word1; #Prints nothing as subroutine2 is unable to access $word1 declared in subroutine1
}
My question, specifically, asks about how could I share a variable ($word1
) declared in one subroutine (subroutine1
) to another subroutine (subroutine2
), that's called inside it (subroutine2
is called inside subroutine1
), ...
subroutine1
)For example we could simply achieved it using one of these three simple well-known ways:
Way 1: declare $word1
as global.
subroutine1 ();
sub subroutine1 {
$word1='hello'; #$word1 is declared as global
subroutine2();
}
sub subroutine2 {
print $word1;
}
Way 2: declare $word1
outside the mother caller subroutine subroutine1
and limit the scope of it.
{
my $word1='hello';
subroutine1 ();
sub subroutine1 {
subroutine2();
}
sub subroutine2 {
print $word1;
}
}
Way 3: pass $word1
as a parameter to subroutine2
.
subroutine1 ();
sub subroutine1 {
my $word1='hello';
subroutine2($word1);
}
sub subroutine2 {
my $x = shift;
print $x;
}
This example is really trivial and can be solved by any simple way including the three above. But building it simple this way and putting those limits in mind (no global variable names collisions, no out-of-subroutine declaration, no parameters usage) will definitely solve my real complicated problem that I couldn't simplify here for now.
If the two subroutines aren't nested, then your request is impossible by definition. If it's visible by two non-nested subs, then it must exist outside of the subs. As such, it must be global, or a declaration outside of the subs must limit its visibility to some lexical scope that includes both subs.
So that leaves nested subs.
sub tree_visitor {
my @rv;
local *_helper = sub {
my ($node) = @_;
push @rv, $node->text;
for my $child ($node->children) {
_helper($child);
}
};
_helper($node);
return @rv;
}
Something closer to what you want is called a "dynamic-scoped variable". It uses a global variable, but the value of the variable is restored after the calling sub exits.
sub subroutine2 {
our $x;
print $x;
}
sub subroutine1 {
local our $x = 'hello';
subroutine2();
}
subroutine1();
It would be must easier to help you if we knew what problem you are actually facing. But it's either going to involve a global var or a closure.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments