Perl :what does "-" means in perl

Viewed 203

what does '-' mean in the param

$cgi->start_html(-title => uc($color), -BGCOLOR => $color);

I just know it is used in hash type, but this is param in a sub. So it makes me confused, and i searched for a long time.

4 Answers

Whenever you come across confusing syntax in Perl, a handy tool is the -MO=Deparse option. This causes Perl to check the syntax of a script and output the script in a normalized form, rather than executing it.

So if I do

perl -MO=Deparse -e '$cgi->start_html(-title => uc($color), -BGCOLOR => $color);'

I get a result of:

$cgi->start_html(-'title', uc $color, -'BGCOLOR', $color);
-e syntax OK

There are three differences here:

  1. Quotes were added to title and BGCOLOR.
  2. The => operators changed to commas.
  3. The parentheses disappeared from uc($color).

The first two are the normal effects of the => ("fat comma") operator: It's equivalent to a comma, except that if the thing to the left is an identifier (starting with a letter or underscore and containing only alphanumeric characters and underscores), that identifier becomes a quoted string.

And the parentheses after uc just aren't strictly necessary in this situation, since the builtin function uc is prototyped to take 0 or 1 arguments.

But now we have -'title' and -'BGCOLOR', so what's the negative of a string? Checking perldoc perlop, we see that unary minus follows the rules:

  1. If the operand is a number or a string representation of a number, does an arithmetic negation.
  2. Otherwise, if the string starts with '+' or '-', switches just the first character of the string to the opposite sign.
  3. Otherwise, if the string starts with a letter, adds a '-' to the beginning of the string.
  4. Otherwise, attempts to convert the string to a number, probably prints a warning if warnings are enabled, and then does an arithmetic negation.

Here we have case 3, so -'title' is '-title' and -'BGCOLOR' is '-BGCOLOR'.

So presumably the start_html method expects a list of arguments which come in key-value pairs, and the key strings are supposed to start with hyphens. (It might or might not internally use these arguments to create a hash, with a line like my %options = @_;.)

This is all a little roundabout, plus you'd get confusing results if you ever tried passing something like -3zzz => $value. So I'd personally add explicit quotes here to make it obvious what's being passed, but keep using the fat commas anyway to emphasize the arguments are meant to be key/value pairs:

$cgi->start_html('-title' => uc($color), '-BGCOLOR' => $color);

It has no effect here. It's just treated as part of the string. I assume that the original author of CGI.pm wanted to make the options look more like command-line options. I think that was a terrible idea.

It's a string literal, just like "-title" or "-BGCOLOR".

perldoc perlop:

[Unary "-" ...] If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. Otherwise, if the string starts with a plus or minus, a string starting with the opposite sign is returned.

In other words, -"foo" is "-foo".

The => operator (sometimes pronounced "fat comma") is a synonym for the comma except that it causes a word on its left to be interpreted as a string if it begins with a letter or underscore and is composed only of letters, digits and underscores.

In other words, foo => 42 is "foo", 42.

Taken together, this means -title => uc($color) is "-title", uc($color).

Related