Re: Difference in Hash Declaration
by moritz (Cardinal) on May 07, 2012 at 07:23 UTC
|
Round parens don't create any substructures. Curly braces create hash references, see perlreftut.
Putting a hash reference in a position where a hash key is expected doesn't make any sense, because it is converted to a string which loses all the interesting information that way.
| [reply] |
Re: Difference in Hash Declaration
by tobyink (Canon) on May 07, 2012 at 07:23 UTC
|
The difference is that Example 2 (using parentheses) is correct and the others are broken.
Braces (i.e. { and }) are used (amongst other things) to create hash references. So...
my %hash = ( foo => 1, bar => 2 );
my $hashref = { foo => 1, bar => 2 };
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] |
Re: Difference in Hash Declaration
by jwkrahn (Abbot) on May 07, 2012 at 11:25 UTC
|
A list can only contain scalar values, for example: ( 1, 'a', [], {}, sub{}, $scalar, \$scalar, \@array, \%hash, \&subroutine, \*type_glob ), (a number, a string, an anonymous array, an anonymous hash, an anonymous subroutine, a scalar variable, a reference to a scalar variable, a reference to an array, a reference to a hash, a reference to a subroutine, a reference to a type glob.)
In Example 1 you are assigning an anonymous hash to an hash, which is the same as saying my %h = {}; or my %h = 'a'; or my %h = 1;. You need to assign a list with an even number of elements.
In Example 2 you are assgning a list of eight elements to the hash. Unfortunately two of the keys are the same as the other two keys so only the last two unique keys are saved to the hash.
Example 3 is basically the same as Example 1.
| [reply] [d/l] [select] |
|
Thank you very much...that was helpful.
| [reply] |
Re: Difference in Hash Declaration
by MidLifeXis (Monsignor) on May 07, 2012 at 13:47 UTC
|
The only one that is syntactically valid is the second one, however, I don't believe that it is doing what you are expecting. Since the parens denote precedence, what Perl reads it as is:
my %sham = (
1 => "j",
2 => "b",
1 => "p",
2 => "b",
);
When assigning to hashes, later insertions with the same key end up replacing any earlier entries with the same key, leaving you with:
my %sham = (
1 => "p",
2 => "b",
);
This can be shown with the use of Data::Dumper or the like. I think what you are intending is:
my @sham = ( # note the sigil
{
1 => "j",
2 => "b",
},
{
1 => "p",
2 => "b",
},
);
Data::Dumper (and any similar module) is a useful tool for visualizing nested data structures.
| [reply] [d/l] [select] |
Re: Difference in Hash Declaration
by anazawa (Scribe) on May 07, 2012 at 08:13 UTC
|
Parenthesis () creates LIST:
( 1 => 'j', 2 => 'b' )
To create a hash, we substitute the LIST for %h:
my %h = ( 1 => 'j', 2 => 'b' );
Incidentally, LIST is different from ARRAY.
To create an array, we substitute LIST for @a:
my @a = ( 1 => 'j', 2 => 'b' );
| [reply] [d/l] [select] |
|
Parenthesis () creates LIST:
print 1, 'b', 3, 'd', 5, 'f', "\n";
I see a list there but I don't see any parentheses.
my @stuff = map $_ + 2, 6, 7, 8, 9, 10;
Ditto
Parentheses are used for precedence.
my %h = ( 1 => 'j', 2 => 'b' );
There the assignment operator has higher precedence than the comma operator so the parentheses are required.
| [reply] [d/l] [select] |
|
I agree with you.
Parentheses don't create LIST, are used for precedence.
I'm glad you pointed out my mistake :)
| [reply] |
Re: Difference in Hash Declaration
by Anonymous Monk on May 07, 2012 at 07:17 UTC
|
#!/usr/bin/perl --
use strict;use warnings;
use Data::Dump qw/ dd /;
my %ro = {
(
1 => "j",
2 => "b",
),
(
1 => "p",
2 => "b",
),
};
my %sham = (
(
1 => "j",
2 => "b",
),
(
1 => "p",
2 => "b",
),
);
my %bo = {
{
1 => "j",
2 => "b",
},
{
1 => "p",
2 => "b",
},
};
dd \%ro;
dd \%sham;
dd \%bo;
__END__
Reference found where even-sized list expected at - line 4.
Reference found where even-sized list expected at - line 28.
{ "HASH(0x3f8c64)" => undef }
{ 1 => "p", 2 => "b" }
{ "HASH(0x99a3bc)" => undef }
| [reply] [d/l] |
|
| [reply] |