in reply to eval & variable names?
The values you pass into a subroutine are aliased, in other words, the elements of @_ are actually the variables you passed in and whatever you do to the elements of @_ happens to the original variables.
Consider:
Output:use Modern::Perl; use PadWalker qw/peek_my peek_our/; my ($first,$second, $third) = qw /1 2 3/; double_me($first,$second, $third); say "$first $second $third"; sub double_me { say get_name(1, $_) for @_; $_*=2 for @_; } sub get_name_my { my $pad = peek_my($_[0] + 1); for (keys %$pad) { return $_ if $$pad{$_} == \$_[1] } } sub get_name_our { my $pad = peek_our($_[0] + 1); for (keys %$pad) { return $_ if $$pad{$_} == \$_[1] } } sub get_name_stash { my $caller = caller($_[0]) . '::'; my $stash = do { no strict 'refs'; \%$caller }; my %lookup; for my $name (keys %$stash) { if (ref \$$stash{$name} eq 'GLOB') { for (['$' => 'SCALAR'], ['@' => 'ARRAY'], ['%' => 'HASH'], ['&' => 'CODE']) { if (my $ref = *{$$stash{$name}}{$$_[1]}) { $lookup{$ref} ||= $$_[0] . $caller . $name } } } } $lookup{\$_[1]} } sub get_name { unshift @_, @_ == 2 ? 1 + shift : 1; &get_name_my or &get_name_our or &get_name_stash }
$first $second $third 2 4 6
CountZero
A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
|
|---|