Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

The default hash - accident, coincidence or conspiracy?

by SimonClinch (Chaplain)
on Jun 20, 2005 at 11:42 UTC ( #468278=perlquestion: print w/ replies, xml ) Need Help??
SimonClinch has asked for the wisdom of the Perl Monks concerning the following question:

As everyone knows, the "default" variable $_ and array @_ have special and well-documented uses. In an idle moment I experimented with %_ using v5.6.1 and lo and behold found that is was indeed predefined and worked as I kind of expected; e.g.

%_ = ( a => 1, b => 2 );

$_{ FRED } = "bert";

and so on like any other hash. However, I can trace no documentation about it. How can I check if it will remain a supported feature? I hope so, because it seems the perfect alternative to global ids to store such information in a predefined data dictionary which is what %_ seems to be for if I had to guess its purpose.

Thanks to all,

Simon Clinch

Comment on The default hash - accident, coincidence or conspiracy?
Re: The default hash - accident, coincidence or conspiracy?
by merlyn (Sage) on Jun 20, 2005 at 11:53 UTC
    What's there to document? It's a variable name that follows all the rules (letters/digits/underscores, but no leading digits). It's available for you to use because it's not also one with a predefined meaning. Actually, @_ and $_ are likewise free for you to use in any way you choose, although some actions in Perl give them initial values that are interesting.

    I would not call it the "default" hash though. There's nothing default about it. {grin}

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

Re: The default hash - accident, coincidence or conspiracy?
by ysth (Canon) on Jun 20, 2005 at 11:55 UTC
    From your example, I'm not sure what you see that is special about %_. Perhaps just that you don't have to declare it with our/use vars when under stricture?

    You should be aware that there is something special about it, though. Just like $_ and @_, if you use it without a package qualifier such as %Foo::_, it references %main::_, not the current package. IIRC, this is indeed documented.

Re: The default hash - accident, coincidence or conspiracy?
by ank (Scribe) on Jun 20, 2005 at 11:58 UTC

    Even though there is currently no special use attached to %_, I would stay away from using it - it can only confuse other programmers when they see $_{$key} or some variation of that.

    -- ank

      That's an argument against the entire Perl language, so I have to disagree. As long as one understands the special globality of the name (as pointed out in several other replies), one should no more avoid %_ than $_ or @_ — or, for that matter, any of the other funky globals.
        Well, maybe that's an argument against the entire Perl 5 language. One should also understand that the "special globality" of the special variables is going away in Perl 6, so something like %_ is going to become lexically scoped rather than globally scoped. So the p5-to-p6 translator is going to have to turn any Perl 6 use of %_ into something like %*_ to make sure the name stays global. Or if we're spiteful enough, it'll turn into %*_P5_EMULATED_GLOBAL_UNDERSCORE_PLEASE_AVOID_ or some such... :-)

        Similar considerations apply to many of the other special variables that need to be rehung on filehandle objects or lexical scopes. And some of the special variables are simply going away, and will have to be emulated by the translator some other way.

        So when people are tempted to rely on idiosyncracies of the Perl 5 implementation, I would remind them of this comment of Henry Spencer's from regexp.h:

        regnode program[1]; /* Unwarranted chumminess with compiler. */

        I don't see how that is an argument against the Perl language - just because you can do something in a certain way doesn't mean that it's desirable to do so.

        As a general rule, I try to avoid potentially confusing code whenever possible. Remember: a good programmer is someone who looks both ways before crossing a one way street.

        -- ank

Re: The default hash - accident, coincidence or conspiracy?
by tlm (Prior) on Jun 20, 2005 at 11:58 UTC

    FWIW, I have seen CPAN modules use %_, though right off the bat I can't remember which. My point is that you can't assume it is free for the taking.

    Personally, I'd stay away from using variables corresponding to unused slots of special variable globs. It's asking for trouble, IMO.

    the lowliest monk

      It is free for the using, if not taking. The local keyword is there to facilitate multiple code chunks using the same global variable independently. It works well enough for $_ and @_, it will work just as well for %_. (That's not to say it's a panacea, though.)

      I don't understand why people think it's asking for trouble. It is no more asking for trouble than using $_ — and I sure wouldn't counsel anyone to avoid using $_. Quite the opposite, in fact.

      That being said, there isn't any really good reason to use %_. The situations in which it would be the most obvious, "natural" name for a variable must be rare indeed.

        I don't understand why people think it's asking for trouble.

        IMO, using package variables in one's code, in general, is asking for trouble (though there may be situations in which one is willing to accept this trouble). Moreover, as I pointed out, some module authors have had the bright idea of using variables such as %_, so one can't be sure that these variables are completely available, and that the other code that uses it is being good about using local whenever it uses the same variables. IMO, having to even worry about these things falls into the category of "trouble." The fact that the docs specifically state that the variables the OP asked about are reserved for Perl's use makes it all the more troublesome to use them.

        the lowliest monk

Re: The default hash - accident, coincidence or conspiracy?
by Animator (Hermit) on Jun 20, 2005 at 12:03 UTC

    The question should not be 'will it be supported', the question should be: 'do you want to use it'?

    It's a real global variable, it lives in the main/default symbol table, you can not lexicalize it, and more important, every file and package can modify it.

    Especially the last point will make it hard to maintain and/or modify and/or integrate it with other programs.

    This is ofcourse all true for $_ and @_, but do you really rely on them having a certain value? I certainly do not.

    Also note that there is no point to have a 'default' hash. You can create a package-global hash (%config for example) which you can access from other packages by including the package name. And if you are not happy with that then you can even import it in other packages.

      Thank you all for such prompt response -- already Animator's point about it being open to modification by any module has persuaded me (sigh) not to use it - pity in a way - it looked so inviting. (-S)
Re: The default hash - accident, coincidence or conspiracy?
by dragonchild (Archbishop) on Jun 20, 2005 at 12:32 UTC
    Use a singleton. Class::Singleton is a good place to start. Anything that is global cannot, by definition, be the perfect alternative to global ids to store such information in a predefined data dictionary.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: The default hash - accident, coincidence or conspiracy?
by tlm (Prior) on Jun 20, 2005 at 12:34 UTC

    From perlop (my added emphasis):

    Perl variable names may also be a sequence of digits or a single punctuation or control character. These names are all reserved for special uses by Perl; for example, the all‐digits names are used to hold data captured by back references after a regular expression match...

    Finally, new in Perl 5.6, Perl variable names may be alphanumeric strings that begin with control characters (or better yet, a caret). These variables must be written in the form "${^Foo}"; the braces are not optional. "${^Foo}" denotes the scalar variable whose name is a con≠trol−"F" followed by two "o"ís. These variables are reserved for future special uses by Perl, except for the ones that begin with "^_" (control−underscore or caret−underscore). No control‐character name that begins with "^_" will acquire a special meaning in any future version of Perl; such names may therefore be used safely.

    the lowliest monk

Re: The default hash - accident, coincidence or conspiracy?
by ank (Scribe) on Jun 20, 2005 at 19:23 UTC

    As an interesting side note, there's a bit on the Perl source code that uses %_ (as part of the obfuscated language tests.) Namely, take a look at: t/japh/abigail.t

    For instance:

    $" = "/"; split // => eval join "+" => 1 .. 7; *{"@_"} = sub {foreach (sort keys %_) {print "$_ $_{$_} "}}; %_ = (Just => another => Perl => Hacker); &{%_};

    -- ank

Re: The default hash - accident, coincidence or conspiracy?
by GrandFather (Cardinal) on Jun 20, 2005 at 20:43 UTC

    The thing of interest is that %_ is accepted as a defined variable by use strict; use warnings;

    use strict; use warnings; %_ = ( a => 1, b => 2 ); print $_ {"a"};

    does not generate any errors or warnings. Maybe that was what OP meant by "predefined"?


    Perl is Huffman encoded by design.
Re: The default hash - accident, coincidence or conspiracy?
by kaif (Friar) on Jun 21, 2005 at 01:12 UTC

    I discovered the %_ variable when I tried to write

    sub foo { # takes a hash argument my %_ = @_; }

    and discovered that that doesn't work. Later, I thought "of course" (because of typeglobs!) and used local %_ instead. Although the presence of "the same" %_ regardless of package may be a problem, as mentioned above, maintaining this should be no more difficult than similar code using $_ and @_.

      Original post: Funny, I tried that out too at some time ... then I realised I just had to convert the array to hash via a list form
      Foo( trouble => brewing ); sub Foo{ my %param = (@_); print "trouble is $param{ trouble }\n"; }

      Update: Oops I missed the quick reference to typeglobs, otherwise I would have replied: What the post I am replying to might have said is that the typeglob *_ has been predefined in the global symbol table, not just the $_ and @_ individually - I could not find a documentation reference to %_ nor *_"

        No, you've completely missed kaif's point. You cannot   my %_   ever. It is illegal. By your response, your solution was to use a different variable name, not "convert the array to hash via a list form".

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://468278]
Approved by holli
Front-paged by holli
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (6)
As of 2014-12-21 10:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (104 votes), past polls