http://www.perlmonks.org?node_id=483357

kwaping has asked for the wisdom of the Perl Monks concerning the following question:

Debugging some ancient code at my company, I came across the following lines inside cgi-lib.cgi (remember that old staple, by Steven E. Brenner?):
$cgi_lib'bufsize = 8192; # default buffer size when reading multi +part $cgi_lib'maxbound = 100; # maximum boundary length to be encounte +rd $cgi_lib'headerout = 0; # indicates whether the header has been +printed
I've never seen variable names with a single quote in them before, so I wrote a very simple test.
#!/usr/bin/perl use strict; use warnings; my $asdf'a = 'hi'; print $asdf'a;

When I ran it, I got the following error (regardless of my strict or warnings settings):
"my" variable $asdf::a can't be in a package near "my $asdf'a "
Can anyone explain what's going on here? It appears that a single-quote can be used in place of :: to declare namespace for variables, but I've never seen or heard of such thing before now. I assume it's a relic from an older Perl version that's now deprecated.

Replies are listed 'Best First'.
Re: Single quotes inside variable names
by jimbojones (Friar) on Aug 12, 2005 at 18:14 UTC
    Hi

    You're correct; it's old-style for ::. From perlmod:
    The old package delimiter was a single quote, but double colon is now the preferred delimiter, in part because it's more readable to humans, and in part because it's more readable to emacs macros. It also makes C++ programmers feel like they know what's going on--as opposed to using the single quote as separator, which was there to make Ada programmers feel like they knew what was going on. Because the old-fashioned syntax is still supported for backwards compatibility, if you try to use a string like "This is $owner's house", you'll be accessing $owner::s; that is, the $s variable in package owner, which is probably not what you meant. Use braces to disambiguate, as in "This is ${owner}'s house".
    - j

Re: Single quotes inside variable names
by borisz (Canon) on Aug 12, 2005 at 18:11 UTC
    Thats oldstyle for $cgi_lib::buffsize. and since the left part of the var is the package it does not work with my.
    Boris
Re: Single quotes inside variable names
by trammell (Priest) on Aug 12, 2005 at 18:57 UTC
    This feature is also the souce of some clever module name (ab)?use, f'rinstance Acme::Don't.

      Don't forget D'oh!



      If God had meant us to fly, he would *never* have given us the railroads.
          --Michael Flanders

Re: Single quotes inside variable names
by ysth (Canon) on Aug 12, 2005 at 18:19 UTC
    Note that the ' to :: translation can trip you up in surprising places:
    %foo = (a'b => "foo"); $foo{c'd} = "foo"; print join "," keys %foo; __END__ a::b,c::d
      I find it's more irksome in a situation like print "You have $person's property!"

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Single quotes inside variable names
by scooper (Novice) on Aug 15, 2005 at 02:21 UTC
    In a similar fashion, ^ was the pipe character in old Unix shells. It isn't supported these days in most shells, but in the old days you'd say ls *.c ^ wc -l instead of today's ls *.c | wc -l
      ls *.c | wc -l
      Of course, that's really the wrong way to write that anyway, since it does a lot more work than necessary, and it also breaks on some combinations of data.

      You've told the shell to expand *.c. It does. Then it passes that to "ls", which takes each argument (and at this point, we already know how many C files there are, so the rest of this is wasted CPU) and looks each file up.

      And ls says "yes, that's a file" and spits it to standard out on a line by itself.

      Or sometimes it does. If there's a directory for that dot-c file instead of a file, you get the contents of the directory. BUG.

      Or, if the filename contains a newline, it takes up more than one line. BUG.

      But then wc gets fired up, counting all those newlines, and replies back with a integer on standard out. Yeah, finally, there's your number, sorta, subject to two classes of bugs and firing off two (or three, if you're trying to catch the output) processes needlessly.

      How should this have been done instead?

      $ set -- *.c; count=$#
      Done. No forking, everything done in the One True Shell (/bin/sh). Far too easy. And not subject to whitespace problems, either spaces or newlines. Admittedly kills the $* array, but by the time you get to this stage, you've generally processed that anyway.

      Your code belongs in a textbook of "how not to code in the shell". The sad part is, you probably copied this from someone else, who probably copied it from someone else. So it becomes this crazy meme that is broken and inefficient, but everyone copies. That's where I come in... the "bad meme killer", similar to my complaints about "useless use of cat" and "bad use of kill -9" and "ref($proto)", and so on.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.