I'm trying to assign hash variables in Perl6 as I would have in Perl. As I'm reading through a file, I take in certain elements and assign to a hash thus:
%key<$barcode><$position> = $sample-id
where in Perl5 this would have been
$key{$barcode}{$position} = $sample_id
I can print the hash assignments after I do so, so I think that the assignment is working.
When I print this hash with
say %key.perl;
this only gives
{"\$barcode" => ${"\$position" => "ZZ12345"}}
How can I print out this multidimensional hash like Perl5's Data::Dumper
or DDP
https://metacpan.org/pod/Data::Printer because say %key.perl
doesn't seem to work for multidimensional hashes?
<>
is the same as {''}
in perl5 so should only be used for string keys. If you want to use the variable names go with :
%key{$barcode}{$position} = $sample_id
this should do the trick.
You can also use the double pointy brace option which does string interpolation.
%key<<$barcode>><<$position>> = $sample_id
You misunderstood the Perl 6 language. (Which is understandable, and not the first time)
Below is an abridged history lesson of the feature you were trying to use.
In Perl 5 you didn't have to quote the key if the only thing between {}
was a bare-word.
use v5.12;
my %hash;
$hash{fubar} = 'abc';
# $hash{'fubar'} = 'abc';
say qq'"@{[ $hash{fubar} ]}"';
# "abc"
That was a special-case, and one of the goals of the Perl 6 design is to have as few special-cases as possible. So the following does not work in Perl 6.
use v6.d;
my %hash;
%hash{fubar} = 'abc';
# %hash{ fubar() } = 'abc';
say qq'"%hash{fubar}"';
# say qq'"%hash{ fubar() }"';
===SORRY!=== Error while compiling ./test.p6
Undeclared routine:
fubar used at lines 4, 7
That error means it failed to even compile.
There is a feature for quote words in both Perl languages.
use v5;
my @array = qw< a b c d >;
use v6;
my @array = qw< a b c d >;
In Perl 6 that can be shortened to
use v6;
my @array = < a b c d >;
qw
is really short for Q :q :w
/ Q :single :words
in Perl 6. Which is enable single-quote behaviour and enable splitting into words. (split on whitespace)
(<>
works because the infix operator <
is not expected there.)
To make up for the automatic bareword quoting between {}
which was not copied over, postcircumfix <>
was added. It combines both of the qw
and {}
features.
use v6;
my %hash;
%hash{qw< foo bar baz >};
%hash{ < foo bar baz >};
%hash< foo bar baz >; # <---
There is an additional more advanced quotewords feature in Perl 6
use v6;
my $a = 'a b "c d"';
say qqww<< $a e f 'g h ' '$a'>>.perl;
say << $a e f 'g h ' '$a'>>.perl;
say « $a e f 'g h ' '$a' ».perl;
# All 3 are exactly equivalent
# ("a", "b", "c d", "e", "f", "g h ", "\$a")
qqww
is short for Q :qq :ww
/ Q :double :quotewords
. Which is enable double-quote behaviour and enable quote-word-splitting.
The :double
is what enables interpolation of $a
.:quotewords
splits up words on spaces, but also allows quotes to control where things get split up.
(Note that :quotewords
happens last)
(qqw
and qww
also work, but there is no shortened way to write them.)
There is also a postcircumfix <<>>
/ «»
.
use v6;
my %hash;
my $a = 'a b "c d "';
%hash{<< $a e f 'g h ' '$a' >>};
%hash<< $a e f 'g h ' '$a' >>;
%hash« $a e f 'g h ' '$a' »;
# All 3 are exactly equivalent to
%hash{'a', 'b', 'c d ', 'e', 'f', 'g h ', '$a'};
# ^^^^^^ ^^^^^^
This sort-of makes it so that postfix <>
is less of a special case.
The reason that a lot of examples use %hash<fubar>
is that it is idiomatic Perl 6.
Perhaps it should be seen as a more advanced feature in the docs and have reduced usage, because you are by far not the first person to make this mistake.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With