Combining statements - a hashref from a hash slice

U

usenet

Greetings. Kindly consider this sample code which illustrates my
question:

#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my @keys = qw{first secnd third};
my @values = qw{aaaaa bbbbb ccccc};

my %hash; # line_A
@hash{ @keys } = @values; # line_B
my $hashref = \%hash; # line_C

print Dumper $hashref;

__END__

As you can see, I have successfully created a reference to a hash which
was created as a hash slice from two regular arrays.

But two things really bother me about my code. First of all, I prefer
to declare and populate a variable in one statement, such as
my $foo = 'bar';
But I can't seem to make this work for %hash; Perl seems to be
confusing context _@_ and data type _{}_ if I try to do this:

my @hash{ @keys } = @values; # No good!

Second, I created %hash (line_B). All I want is the reference, and it
could be a reference to an anomyous hash for all I care. I don't really
want to create a named hash just to make a reference to it. But I
cannot figure out how to simply do:

my %hashref = [something to do with @keys and @values]

I think I should be able to combine line_A, line_B, and line_C into one
fairly simple and elegant statement, but I cannot figure out how.

Thanks!
 
A

A. Sinan Unur

(e-mail address removed) wrote in @y43g2000cwc.googlegroups.com:
#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my @keys = qw{first secnd third};
my @values = qw{aaaaa bbbbb ccccc};

my %hash; # line_A
@hash{ @keys } = @values; # line_B
my $hashref = \%hash; # line_C

print Dumper $hashref;

__END__
....

my %hashref = [something to do with @keys and @values]

I think I should be able to combine line_A, line_B, and line_C into
one fairly simple and elegant statement, but I cannot figure out how.

If you don't mind using List::MoreUtils:

my $hash = { pairwise
{ $a => $b }
@{ [ qw{first secnd third} ] },
@{ [ qw{aaaaa bbbbb ccccc} ] },
};

Now, this actually gives a warning about $a and $b being used only once
which I don't exactly understand why.

Declaring $a and $b with our gets rid of the warning, but

D:\Home\asu1\UseNet\clpmisc> cat hhh.pl
#!/usr/bin/perl

use strict;
use warnings;

use List::MoreUtils qw( pairwise );

my $hash;

{
local our ($a, $b);
$hash = { pairwise
{ $a => $b }
@{ [ qw{first secnd third} ] },
@{ [ qw{aaaaa bbbbb ccccc} ] },
};
}

use Data::Dumper;
print Dumper $hash;

D:\Home\asu1\UseNet\clpmisc> hhh
Attempt to free unreferenced scalar: SV 0x1a19094, Perl interpreter:
0x34e94 at
D:\Home\asu1\UseNet\clpmisc\hhh.pl line 20.
Attempt to free unreferenced scalar: SV 0x18d40dc, Perl interpreter:
0x34e94 at
D:\Home\asu1\UseNet\clpmisc\hhh.pl line 20.
$VAR1 = {
'first' => 'aaaaa',
'secnd' => 'bbbbb',
'third' => 'ccccc'
};

Could someone tell me what would be the right way to do this? Isn't it
correct to localize $a and $b?

Sinan
--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
B

Brad Baxter

Greetings. Kindly consider this sample code which illustrates my
question:

#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my @keys = qw{first secnd third};
my @values = qw{aaaaa bbbbb ccccc};

my %hash; # line_A
@hash{ @keys } = @values; # line_B
my $hashref = \%hash; # line_C

print Dumper $hashref;

__END__

As you can see, I have successfully created a reference to a hash which
was created as a hash slice from two regular arrays.

But two things really bother me about my code. First of all, I prefer
to declare and populate a variable in one statement, such as
my $foo = 'bar';
But I can't seem to make this work for %hash; Perl seems to be
confusing context _@_ and data type _{}_ if I try to do this:

my @hash{ @keys } = @values; # No good!

I think this will prove a problem. A slice is not a kind of animal
that can be declared.
Second, I created %hash (line_B). All I want is the reference, and it
could be a reference to an anomyous hash for all I care. I don't really
want to create a named hash just to make a reference to it. But I
cannot figure out how to simply do:

my %hashref = [something to do with @keys and @values]

I think I should be able to combine line_A, line_B, and line_C into one
fairly simple and elegant statement, but I cannot figure out how.

This is fairly simple, even if it is two statements:

my $hashref;
@$hashref{ qw{a b c} } = qw{1 2 3};

And this sort of craziness comes to mind, but I wouldn't take
it too seriously:

my $hashref = (@_{@{[qw[a b c]]}}=@{[qw[1 2 3]]},\%_);

and similarly:

my $hashref = sub{@_{@{$_[0]}}=@{$_[1]};\%_}->
([qw[a b c]],[qw[1 2 3]]);
 
B

Brad Baxter

I'm partial to Randal's suggestion from the previous round
of discussions. A slight modification gives you:

use Data::Dumper;

@{$$_}{qw/foo bar baz/} = (1, 2, 3) for \my $hashref;
print Dumper $hashref;

Ah, yes, leave it to Randal. I obviously missed that round.
But this seems to work:

@{$_}{qw/foo bar baz/} = (1, 2, 3) for my $hashref;

Why the extra reference?
 
P

Peter Scott

But two things really bother me about my code. First of all, I prefer
to declare and populate a variable in one statement, such as
my $foo = 'bar';
But I can't seem to make this work for %hash; Perl seems to be
confusing context _@_ and data type _{}_ if I try to do this:

my @hash{ @keys } = @values; # No good!

I think I should be able to combine line_A, line_B, and line_C into one
fairly simple and elegant statement, but I cannot figure out how.

Can't be done without dropping the 'simple and elegant' constraint.

You are not the first person to want this. A patch to allow it was
submitted once but there were problems with the ramifications and it was
dropped. See
http://groups.google.com/group/perl.perl5.porters/browse_thread/thread/cf795c864b4a52de
 
X

xhoster

Greetings. Kindly consider this sample code which illustrates my
question:

#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my @keys = qw{first secnd third};
my @values = qw{aaaaa bbbbb ccccc};

my %hash; # line_A
@hash{ @keys } = @values; # line_B
my $hashref = \%hash; # line_C

print Dumper $hashref;

__END__

As you can see, I have successfully created a reference to a hash which
was created as a hash slice from two regular arrays.

But two things really bother me about my code. First of all, I prefer
to declare and populate a variable in one statement, such as
my $foo = 'bar';
But I can't seem to make this work for %hash; Perl seems to be
confusing context _@_ and data type _{}_ if I try to do this:

Sadly, Perl doesn't let you do that. I suspect that Perl is not suffering
from any confusion, it simply refuses out of stubborn clarity.
my @hash{ @keys } = @values; # No good!

Second, I created %hash (line_B). All I want is the reference, and it
could be a reference to an anomyous hash for all I care. I don't really
want to create a named hash just to make a reference to it. But I
cannot figure out how to simply do:

my %hashref = [something to do with @keys and @values]

my $hashref;
@{$hashref}{@keys}=@values;

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top