Re^2: when is "my" not necessary?
by argv (Pilgrim) on Nov 02, 2004 at 23:48 UTC
|
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;
| [reply] [d/l] [select] |
|
|
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).
| [reply] [d/l] |
|
|
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. | [reply] [d/l] [select] |
|
|
Only lexicals have scope which is why they're "the right thing".
You can learn all this and more by reading perldata. RTFM.
| [reply] |
|
|
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
| [reply] [d/l] [select] |
|
|
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
| [reply] [d/l] [select] |
|
|
|
|