in reply to Re: when is "my" not necessary?
in thread when is "my" not necessary?

thanks for everyone's reply. So my two main questions now are:

Just why are lexicals "the right thing?" Both clearly have their uses and their purposes (and scopes), but is it really that one is "the right thing?", or is it just the you have to use the appropriate method at the appropriate time?

The second question is, what is the advantage of using this form of hash:

my $hash; $hash{foo} = bar;
vs. this form of hash:
my $hash = {}; $hash->{foo} = bar;

Replies are listed 'Best First'.
Re^3: when is "my" not necessary?
by revdiablo (Prior) on Nov 03, 2004 at 00:20 UTC
    Just why are lexicals "the right thing?"

    Unless you are very careful to use local, package variables (the kind you get when you don't use my) are always global. Even when you do use local, there are many surprises waiting in store. Package variables make action at a distance far too easy.

    Lexical variables, on the other hand, are usually very safe. You know that when you scope a lexical variable to a specific block, nothing outside of that block can access it. You also know that you are not clobbering any other variables of the same name from other scopes. It's just the right way to go 99.95% of the time. The whole history of computer science has proved this out -- people are constantly thinking of new ways to keep pieces of code from inadvertantly interacting with and breaking other pieces of code.

    The second question is, what is the advantage of using this form of hash . . . vs. this form of hash

    The first one you showed was a hash, the second was a hash reference. References are very useful for a variety of reasons, but unless you actually need one, I advise sticking with a plain hash. I have no objective reasons, other than reducing the amount of unnecessary syntax (which, especially when writing Perl code, is always something to strive for).

Re^3: when is "my" not necessary?
by runrig (Abbot) on Nov 03, 2004 at 01:04 UTC
    my $hash; $hash{foo} = bar;
    Once again, you are not using strict (and you have two different variables named 'hash'). The first line above refers to the lexical scalar variable $hash (which in your second example you use as a hash reference, which is just another type of scalar); the second line, assuming there is nothing else in this program, is referring to the package variable %main::hash. If you wanted to make a lexical hash you would go:
    my %hash; $hash{foo} = 'bar';
    You should use strict, as your second line also uses the bare word 'bar', which gets interpreted as a string, but is a dangerous thing to rely upon, and won't work under strict anyway (and assigining to the undeclared hash is also not allowed under strict). Maybe a look through perldata is in order.
Re^3: when is "my" not necessary?
by Anonymous Monk on Nov 03, 2004 at 00:01 UTC
    Only lexicals have scope which is why they're "the right thing". You can learn all this and more by reading perldata. RTFM.
Re^3: when is "my" not necessary?
by radiantmatrix (Parson) on Nov 03, 2004 at 19:45 UTC

    Well...

    my $hash; $hash{foo} = bar;
  • Creates a lexical scalar named $hash
  • Assigns 'bar' to the key 'foo' in the global variable %hash (or, more accurately, %main::hash)

    If you meant:

    my %hash; $hash{foo} = 'bar'; #Versus my $hash = {}; $hash->{foo} = 'bar';

    Then there is still a difference. In the first, you create a lexical hash named %hash, then assign a value to one of it's keys. In the second you create a lexical scalar which contains an anonymous reference to a hash.

    To examine the difference, run this:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; print "A lexical hash:\n"; my %hash; $hash{foo} = 'bar'; print Dumper(\%hash); print "A lexical hash *reference*:\n"; my $hash = {}; $hash->{foo} = 'bar'; print Dumper(\$hash);
    Note how the variable in the second case "points to" (is a reference to) the actual hash, while the first case is just the hash. I highly suggest reading up on references, and man perlvar -- the nuances are important and often incredibly useful. ;-)

    radiantmatrix
    require General::Disclaimer;
    "Users are evil. All users are evil. Do not trust them. Perl specifically offers the -T switch because it knows users are evil." - japhy
      Folks, as lovely and complete as your responses were, they were merely explanations for the differences between %hash{} and $hash->{}. My question, however, was what is the advantage of using one over the other? Obviously, there are contextual sitautions where you are supposed to use one instead of the other, but in cases where you are just creating a dynamically growing hash, does it matter which?

      If the question is still too simple to answer one way or another, how about answering this: under what conditions is one more efficient memory-wise, performance-wise, or otherwise?


      Independently of that question, let me throw in this: I have a text file that I parse with perl and build hashes based on that data. Think of it as a cross-referencing dataset with references pointing every which way. In order to avoid reparsing this each and every time the program starts up (it'll be a cgi script, and the data it reads is static), what would be the best way to just dump the hashes into a file and load it back up in one swell foop so as to optimize performance? Would the above "Dumper" package be a good choice? And in this case, would I want to use the hash reference form discussed above?

      dan

        what is the advantage of using one over the other?

        The syntax when dealing with hashes is simpler than when dealing with hash references. When I want to pass them around as arguments though, I tend to use hash references instead. And if you want a hash to be part of a larger data structure, you have no choice but to use references (unless you use a glob, but let's not go there).

        what would be the best way to just dump the hashes into a file and load it back up in one swell foop so as to optimize performance? Would the above "Dumper" package be a good choice? And in this case, would I want to use the hash reference form discussed above?

        Data::Dumper is good for "seeing" the contents of a data structure for debugging purposes, but for storing and retrieving data, Storable deals better with things like odd characters such as line feeds in the data, though the file it creates is not readable like the output of Data::Dumper. You can also look at things like DBM::Deep (update: or YAML or XML (e.g. XML::Simple) modules).