jesuashok has asked for the wisdom of the Perl Monks concerning the following question:
Hi all,
my $pat =
{qw(a - b = c ~ d ^)}->{substr($0, 0, 1)};
what the above code does? I am interested to know the above functionality
"Keep pouring your ideas"
Re: Interesting line which I read from Monk's snippets
by Tanktalus (Canon) on Jan 31, 2006 at 04:38 UTC
|
qw(a - b = c ~ d ^) creates a list: "a", "-", "b", "=", "c", "~", "d", "^". Put that in braces, and you are initialising an anonymous hash. Use the arrow to dereference that hash. The brace to the right shows what key to use to dereference the hash. The key to use is the substring of $0 (the program name) - starting at position 0, length of 1.
It's like this:
my %underline = (
a => '-',
b => '=',
c => '~',
d => '^',
);
my $first_letter = substr($0, 0, 1);
my $pat = $underline{$first_letter};
Just a bit more concisely, and much less readably.
It's a cute trick, but I wouldn't recommend learning how to code from it ;-) | [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
Re: Interesting line which I read from Monk's snippets
by gryphon (Abbot) on Jan 31, 2006 at 05:32 UTC
|
Greetings jesuashok,
It's a very curious line, and others have explained what it does already; however, it has a couple negatives: It's not easily understood, and it's slower than a more easily understood alternative.
use strict;
use warnings;
use Benchmark qw(cmpthese);
cmpthese(
100000,
{
'ahash' => sub {
my $pat = {qw(a - b = c ~ d ^)}->{substr($0, 0, 1)};
},
'tr' => sub {
(my $pat = substr($0, 0, 1)) =~ tr/abcd/-=~^/;
},
},
);
The above benchmark returns this:
Rate ahash tr
ahash 75120/s -- -86%
tr 541712/s 621% --
It's a nice trick, but I wouldn't use it anywhere except in an obfu.
gryphon
Whitepages.com Development Manager (WDDC)
code('Perl') || die;
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
To deliver the same result (i. e. undef) for not found input values, the tr solution has to be a bit more elaborate.
Somewhat along the line of
my $found = (my $pat = substr($0,0,1)) =~ tr/abcd/-=~^/;
$pat = $found ? $pat : undef;
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Interesting line which I read from Monk's snippets
by davidrw (Prior) on Jan 31, 2006 at 04:39 UTC
|
First, start with substr($0, 0, 1) ... perlvar tells us that $0 is the name of the program running .. perlfunc tells us about substr, and so this clause is getting the first letter of the program being run.
Now, let's look at {qw(a - b = c ~ d ^)} .. This is creating a hashref, with a, b, c, d as the keys and the characters: - = ~ ^ as the values.. to see this, do:
perl -MData::Dumper -e 'print Dumper {qw(a - b = c ~ d ^)}'
# OUTPUT:
$VAR1 = {
'a' => '-',
'b' => '=',
'c' => '~',
'd' => '^'
};
And putting those together, you end up w/$pat being one of those four values characters if the first letter of $0 is a, b, c, or d. Otherwise it will be undef.
why is this being done? I dunno -- would have to see the context.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Interesting line which I read from Monk's snippets
by chanio (Priest) on Jan 31, 2006 at 22:50 UTC
|
I need to try $0 first!
If I am calling the script from far away (for example in windows: C:\perl\bin\eraseme.pl) , then $0 has also the path attached to the name... ($0 eq 'C:\perl\bin\eraseme.pl'). So, it would not work as expected.
I should first, get rid of the path...
$0=~s/^.*[\\\/]//;
UPDATE: see a better way with liverpole's comment.
| [reply] [Watch: Dir/Any] [d/l] |
|
An easier way to get rid of the path is:
use File::Basename;
my $iam = basename $0;
I used to use a regex substitution instead, and my fingers still "remember" the sequence:
(my $iam = $0) =~ s,.*/,,;
But when I started coding in Perl for Windows in addition to (Li|U)n[ui]x, it was unwieldy to use a regex which accounted for all the different pathname symbols. Someone told me about the File::Basename method, and I've used it ever since; it's easier to remember, easier to type, and part of the standard Perl distro on both systems.
@ARGV=split//,"/:L";
map{print substr crypt($_,ord pop),2,3}qw"PerlyouC READPIPE provides"
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|