Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "%_" in perl?

Tags:

perl

I've just been given a code snippet:

@list = grep { !$_{$_}++ } @list; 

As an idiom for deduplication. It seems to work, but - there's no %_ listed in perlvar.

I'd normally be writing the above by declaring %seen e.g.:

my %seen; my @list = grep { not $seen{$_}++ } @list; 

But %_ seems to work, although it seems to be global scope. Can anyone point me to a reference for it? (Or at least reassure me that doing the above isn't smashing something important!)

like image 532
Sobrique Avatar asked Sep 29 '15 14:09

Sobrique


People also ask

What is meaning of $_ in Perl?

The most commonly used special variable is $_, which contains the default input and pattern-searching string. For example, in the following lines − #!/usr/bin/perl foreach ('hickory','dickory','doc') { print $_; print "\n"; }

What does @_ in Perl mean?

Using the Parameter Array (@_)Perl lets you pass any number of parameters to a function. The function decides which parameters to use and in what order.

What does =~ mean in Perl?

=~ is the Perl binding operator. It's generally used to apply a regular expression to a string; for instance, to test if a string matches a pattern: if ($string =~ m/pattern/) {

What is @$ in Perl?

It's a dereference. $tp is a reference to an array. @$tp says "dereference and give me the values", it could also be written as @{$tp} .


1 Answers

It's a hash. You can have a hash named _ because _ is a valid name for a variable. (I'm sure you are familiar with $_ and @_.)

No Perl builtin currently sets it or reads %_ implicitly, but punctuation variables such as %_ are reserved.

Perl variable names may also be a sequence of digits or a single punctuation or control character (with the literal control character form deprecated). These names are all reserved for special uses by Perl


Note that punctuation variables are also special in that they are "super globals". This means that unqualified %_ refers to %_ in the root package, not %_ in the current package.

$ perl -E'    %::x    = ( name => "%::x"    );    %::_    = ( name => "%::_"    );    %Foo::x = ( name => "%Foo::x" );    %Foo::_ = ( name => "%Foo::_" );     package Foo;     say "%::x    = $::x{name}";    say "%::_    = $::_{name}";    say "%Foo::x = $Foo::x{name}";    say "%Foo::_ = $Foo::_{name}";     say "%x      = $x{name}";    say "%_      = $_{name}"; ' %::x    = %::x %::_    = %::_ %Foo::x = %Foo::x %Foo::_ = %Foo::_ %x      = %Foo::x %_      = %::_      <-- surprise! 

This means that forgetting to use local %_ (as you did) can have very far-reaching effects.

like image 152
ikegami Avatar answered Sep 21 '22 23:09

ikegami