Perl contains many magic variables (also "special" or "system"), which affect program execution:
$_ — the default variable for many operators (foreach, map, grep, while <>, etc.).@_ — an array of incoming arguments within subroutines.%SIG — a hash with operating system signal handlers.my @nums = (1,2,3); foreach (@nums) { $_ *= 2; # modifies the original array! } sub show_args { print "First: ", $_[0], " "; } show_args('a','b'); # $_[0] = 'a' $SIG{INT} = sub { print "Caught Ctrl-C "; exit; };
Caution: many magic variables are modified implicitly; incorrect handling can affect the global state of the program.
Is it safe to use the global variable $_ in several nested loops or subroutines?
Answer: No, because a nested loop or subroutine often overwrites $_, leading to the loss of the value in the outer context. It is recommended to use explicit variables:
foreach my $x (@a) { foreach my $y (@b) { ... } }
Story
In a script for processing large logs, a while(<FH>) {...} loop was used. Inside the loop, a function was called that, in turn, called map without its own variable specification, which corrupted $_ in the outer loop, causing lines to be skipped.
Story
When handling signals through %SIG, the developer replaced the __DIE__ handler, but did not consider that this affects the behavior of the entire process, including third-party modules, resulting in uncontrolled termination on errors in external code.
Story
Optimizing argument passing through a reference to an array (@_) within a subroutine and attempting to change its values directly without explicit copying led to unexpected changes in variables in the outer code.