NAME
subtlety - the subtle things about perl
QUIRKS
The following is a list of some of the things that have surprised me about Perl.
+shift;
This feature of Perl represented the first (and only?) time Keith <<A HREF="mailto:keith@lbox.org>">keith@lbox.org> stumped me w/ a Perl question. The most common use of shift is to take parameters off of @_ and put them into scalars.
sub foo { my $self = shift; my $hash_ref = shift;
# and so on... }
What if you wanted to have a local copy of the hash instead of working directly with the hash reference? You can't say:
my %hash = %{ shift };
The reason for this is because perl doesn't know whether you mean %shift or whether you're trying to execute the built-in shift. To remedy this (w/o using more variables) you can say:
my %hash = %{ +shift };
Now it works. Why?! The unary + operator is a hint to the perl interpreter that it's not a variable name (because variable names cannot start w/ a ``+''). shift can still be a built-in at this point so that's what the perl interpreter treats it as. By the time %{ } comes around, shift has returned a a hash reference that can be cast into a hash. The + binds tighter than the %{ }.
Another (less obfuscated) way of doing this is:
my %hash = %{ shift() };
The () binds tighter than the %{ }, so this achieves the same thing.
Perl built-ins are not subroutines.
I wrote a script called lchtml that would lowercase HTML tags and attributes while leaving the rest of the content alone. I thought it would be nice to be able to uppercase these things as well, so my first thought was to make it so that the routines that did the text transformation could take a subroutine reference as a parameter. When I wanted to lowercase, I'd give it \&lc and when I wanted to uppercase, I'd give it \&uc.
It didn't work. The built-in functions lc and uc (or any other built-in for that matter) aren't really subroutines. You can't take their reference. This was the first time I felt deep disappointment in Perl. I accept the fact that Perl is not 'orthogonal', but this was a little too far.
My work-around was to create wrapper subroutines that looked like:
sub my_lc { lc +shift; } sub my_uc { uc +shift; }
and pass around references to these wrapper subroutines. It made me feel dirty.
Sub-expression matches in array context.
Note that the following printf is receiving its parameters from the sub-expressions in the regular expression.
printf("#%02x%02x%02x %s\n", /(\d+)\s+(\d+)\s+(\d+)\s+(.*)/);
In array context, the sub-expressions ($1, $2, $3, ...) will be returned as a list.
The difference between <STDIN> and <>.
One would think that <> would just read from STDIN, but what if there's nothing to be read from STDIN? Did you know <> will try to iterate over @ARGV, instead? It'll try to open each thing in @ARGV as if it were a file, and then try to read from that file. Make a script that does:
#!/usr/bin/perl while (<>) { print "$_\n"; }
and then invoke it like:
$ ./script a b c Can't open a: No such file or directory Can't open b: No such file or directory Can't open c: No such file or directory
If any of those files (a, b, or c) were to exist, it would have printed them to STDOUT. If the script had said <STDIN>, @ARGV would have been left alone.
\ is a list operator
Usually, one uses \ in scalar context to get the reference of one thing, but you can also use it in array context.
@ref = \($a, $b, $c);
will take the reference of $a, $b, and $c and put them in @ref. If you ever need to take the reference of a bunch of things at once, this might be the idiom to use.
Mixing long and short options with Getopt::Long
This is documented under the ``Aliases and Abbreviations'' section of Getopt::Long's man page, but if you're not reading carefully, you will miss it. You can specify alternatives to an option by separating them with the pipe character |. Suppose you wanted people to be able to specify a size on the command line. If you want them to have the option to use either ``--size'' or ``-s''. To do this you can say:
my %opt; GetOptions(\%opt, "size|s=i");
SEE ALSO
Perl Monks -- you pick up on a lot of weird things perl can do.
|
---|
Replies are listed 'Best First'. | |
---|---|
<> and @ARGV
by chip (Curate) on Jul 28, 2000 at 15:23 UTC | |
by beppu (Hermit) on Jul 28, 2000 at 16:20 UTC | |
by chip (Curate) on Jul 28, 2000 at 22:59 UTC | |
RE: Subtle Quirks
by autark (Friar) on Jul 28, 2000 at 19:28 UTC | |
by merlyn (Sage) on Jul 28, 2000 at 19:33 UTC | |
by PipTigger (Hermit) on Jul 30, 2000 at 11:58 UTC | |
by autark (Friar) on Jul 31, 2000 at 07:43 UTC | |
Of course &lc doesn't work
by chip (Curate) on Jul 28, 2000 at 15:20 UTC | |
by beppu (Hermit) on Jul 28, 2000 at 16:07 UTC | |
by chip (Curate) on Jul 28, 2000 at 22:54 UTC | |
RE: Subtle Quirks
by turnstep (Parson) on Jul 29, 2000 at 07:57 UTC | |
by beppu (Hermit) on Jul 29, 2000 at 19:08 UTC | |
by davorg (Chancellor) on Jul 29, 2000 at 19:21 UTC |