develooper Front page | perl.perl6.users | Postings from January 2019

Re: I need hash inside a hash help

Thread Previous | Thread Next
From:
Bruce Gray
Date:
January 11, 2019 19:45
Subject:
Re: I need hash inside a hash help
Message ID:
96F2B824-7C52-4960-8FE6-08D635963745@acm.org
Short answer: use `%hash{$var}`, not `%hash<$var>`.

When they are not in position to be less-than and greater-than comparison operators, the pair of left and right angle brackets are a circumfix operator that work like Perl 5’s “quote word” op: `qw()`.

In Perl 6, `<>` are used a lot, including as a shortcut in hash lookups.
The full form for looking up the constant key `acme` in %Vendors is to use curly braces and to *quote* the key (single or double quote), or have the key in a variable:
	say %Vendors{'acme’};
	say %Vendors{"acme”};
	my $k = ‘acme’;
	say %Vendors{$k};
The shortcut of replacing the curly braces with angle brackets only works for constant strings:
	say %Vendors<acme>;

Advanced note: Since `<>` produce a *list* of quoted words, you can use them to extract multiple values from a hash:
	my ( $acct, $cn ) = %Vendors{"acme"}{"AccountNo", "ContactName”};
	my ( $acct, $cn ) = %Vendors<acme><AccountNo ContactName>;
	say [:$acct, :$cn].perl;

-- 
Hope this helps,
Bruce Gray (Util of PerlMonks)



> On Jan 11, 2019, at 1:25 PM, ToddAndMargo via perl6-users <perl6-users@perl.org> wrote:
> 
> On 1/11/19 11:16 AM, Bruce Gray wrote:
>>> On Jan 11, 2019, at 12:41 PM, ToddAndMargo via perl6-users <perl6-users@perl.org> wrote:
>>> 
>>> Hi All,
>>> 
>>> How do I do a hash inside a hash?
>>> 
>>> So far I have:
>>> 
>>> $ p6 'my %Vendors=("acme" => ( "ContactName" => "Larry, "AccountNo" => 1234 ) ); say %Vendors;'
>>> ===SORRY!=== Error while compiling -e
>>> 
>>> 
>>> I want to be able to have both a Contact Name and and AccountNo
>>> associated with each key in %Vendors.
>>> 
>>> 
>>> Many thanks,
>>> -T
>> First, you need a double-quote after `Larry` (before the comma) to fix the syntax error:
>> 	perl6 -e 'my %Vendors=("acme" => ( "ContactName" => "Larry", "AccountNo" => 1234 ) ); say %Vendors;'
>> At this point, you have a Hash of List of Pairs. To change it into a Hash of Hashes, change the inner parens to curly braces:
>> 	perl6 -e 'my %Vendors=("acme" => { "ContactName" => "Larry", "AccountNo" => 1234 } ); say %Vendors; say %Vendors<acme><AccountNo>;'
>> Those inner parens were acting as an anonymous list constructor, but you needed an anonymous *hash* constructor, which is what the curly braces do (when they are not doing their code-block-ish job).
>> You could have also used `Hash(…)` or `%(…)` instead of `{…}`, but `{…} is shortest, and most traditional from Perl 5.
>> —
>> Hope this helps,
>> Bruce Gray (Util of PerlMonks)
> 
> Hi Bruce,
> 
> Thank you!
> 
> This works,
> 
> $ p6 'my $x="Ace"; my %Vendors=("acme" => { "ContactName" => "Larry", "AccountNo" => 1234 }, "Ace" => { "ContactName" => "Mo", "AccountNo" => "A102" } ); say "%Vendors<Ace><ContactName>" ~ "\t" ~ "%Vendors<Ace><AccountNo>";'
> Mo	A102
> 
> 
> but I have to access it by a variable.  "Now" what am I doing wrong?
> 
> $ p6 'my $x="Ace"; my %Vendors=("acme" => { "ContactName" => "Larry", "AccountNo" => 1234 }, "Ace" => { "ContactName" => "Mo", "AccountNo" => "A102" } ); say "%Vendors<$Ace><ContactName>" ~ "\t" ~ "%Vendors<$Ace><AccountNo>";'
> Use of uninitialized value of type Any in string context.
> 
> 
> Many thanks,
> -T

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About