Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??


subtlety - the subtle things about perl


The following is a list of some of the things that have surprised me about Perl.


This feature of Perl represented the first (and only?) time Keith <<A HREF=">">> 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");


Perl Monks -- you pick up on a lot of weird things perl can do.

In reply to Subtle Quirks by beppu

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others about the Monastery: (4)
    As of 2018-01-23 22:25 GMT
    Find Nodes?
      Voting Booth?
      How did you see in the new year?

      Results (254 votes). Check out past polls.