Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
P is for Practical
 
PerlMonks  

Replace Hash-Ref with Array-Ref

by Anonymous Monk
on Nov 08, 2012 at 08:53 UTC ( #1002841=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm trying to replace a Hash-Ref with an Array-Ref. Here's a simplified code-snippet for your understanding:

use Data::Dumper; my $ref = { "baz" => [1,2,3,4] }; print Dumper $ref; foo($ref); #$ref should be [1,2,3,4] now print Dumper $ref; sub foo { my $bar = shift; $bar = $bar->{baz}; #(1) #@$bar = @{$bar->{baz}}; #(2) print Dumper $bar; }

I want that at the end $ref contains a reference to $ref->{baz}. This has to be done in a sub. My first try was (1), but it failed because it only changes $bar. My second try would have been (2), but this fails because $bar (and $ref) is an Hash-Ref.

Is there a way to accomplish this at all?

Thanks for you help, Markus

Comment on Replace Hash-Ref with Array-Ref
Download Code
Re: Replace Hash-Ref with Array-Ref
by brx (Pilgrim) on Nov 08, 2012 at 09:02 UTC
    I want that at the end $ref contains a reference to $ref->{baz}.

    use Data::Dumper; my $ref = { "baz" => [1,2,3,4] }; print Dumper $ref; sub bazify {return $_[0]->{baz} }; $ref = bazify($ref); print Dumper $ref;

    update: note that it is not a reference to $ref->{baz}, but its value (which is a ref to an anonymous array)

    English is not my mother tongue.
    Les tongues de ma mère sont "made in France".
Re: Replace Hash-Ref with Array-Ref
by tobyink (Abbot) on Nov 08, 2012 at 09:05 UTC

    Technique, the first: we just assign a new reference to $ref, so that the pointer is pointing to the baz array.

    use Data::Dumper; my $VAR1 = { "baz" => [1,2,3,4] }; my $VAR2 = $VAR1; print "BEFORE\n", Dumper($VAR1, $VAR2); # Note $VAR1 is changed, but $VAR2 is still the hashref. replace_ref($VAR1); print "AFTER\n", Dumper($VAR1, $VAR2); sub replace_ref { $_[0] = $_[0]{baz}; }

    Technique, the second: we actually swap the hash and array around in memory. This swaps all references to them!

    use Data::Dumper; use Data::Swap; my $VAR1 = { "baz" => [1,2,3,4] }; my $VAR2 = $VAR1; print "BEFORE\n", Dumper($VAR1, $VAR2); # Note that both $VAR1 and $VAR2 are changed. replace_ref($VAR1); print "AFTER\n", Dumper($VAR1, $VAR2); sub replace_ref { swap $_[0], $_[0]{baz}; }
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Thanks! Technique, the first was exactly what I was looking for.

      I think I'll read a bit more about @_.

        Mind you, it's far from kosher to have functions that mess with its arguments. You save, what, five characters each function call? Try to do it how brx suggested.

        sub bazify { my ($bar) = @_; return $bar->{baz}; } $ref = bazify($ref);

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1002841]
Approved by tobyink
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2014-04-19 20:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (483 votes), past polls