copy "sub" hash?

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
how can you extract "mary" into another hash?

%a = ('mary'=>
         {'address'=>11, 'zip'=>12},
         {'address'=>21, 'zip'=>22},

%b = $a;  ???

Re: copy "sub" hash?

On 05/26/2014 06:32 PM, wrote:
Quoted text here. Click to load it

You are copying a reference above.

If you were to (attempt) to print out $b you should see  
something like:

my %a = ('mary'=>
          {'address'=>11, 'zip'=>12},
          {'address'=>21, 'zip'=>22},

my %b = $a;

print qq~$b\n~;

Output ->
Reference found where even-sized list expected
Use of uninitialized value $b in concatenation (.) or string

Copying the dereferenced value of 'mary' instead:

my %a = ('mary'=>
          {'address'=>11, 'zip'=>12},
          {'address'=>21, 'zip'=>22},

my %b = %};

print qq~$b\n~;

Output -> 11

The outer brackets are not mandatory, but I tend to use them in  
dereferencing as they are an immediate visual clue as to what the code  
is doing.

You could also (simpler in my book) simply take a reference rather than  
copy into another hash if that works for your process....

my %a = ('mary'=>
          {'address'=>11, 'zip'=>12},
          {'address'=>21, 'zip'=>22},

my $mary = $a;

print $mary->;

Output -> 11

It might be worth your time to get a handle on references... You WILL  
need them sooner or later regardless and OOP is pretty much a mystery  
unless you understand them.



Re: copy "sub" hash?

Quoted text here. Click to load it


Quoted text here. Click to load it

Not really. Assigning a list to a hash causes the contents of the list
to be turned into key/value pairs as they're encountered, eg this code

[rw@sable]~#perl -e '%h = qw(a 1 b 2); print($h, ", ", $h, "\n")'
1, 2

causes %h to contain a key 'a' which is mapped to 1 and a key 'b' mapped
to 2. $a returns the value associated with the key 'mary' in the
hash %a. This is a reference to a hash. Since there's no other value,
this is effectively a list of size 1. An attempt to use a reference as
hash key will end up using the stringification of the reference instead,
consequently, what

%b = $a

does is create a key a la 'HASH(0x8195c70)' in %b whose corresponding
value is undef.


Quoted text here. Click to load it


Quoted text here. Click to load it

They are mandatory in this case:

[rw@sable]~#perl -e '$h = {h => a}; print %$h;'
syntax error at -e line 1, near "$h{a"
Execution of -e aborted due to compilation errors.

The exact rules are (quoted from memory) that a simple, scalar variable
holding a reference of the appropriate type can be used anywhere an
identifier could appear as well. Further, a block returning a reference
of an appropriate type can be used instead of the 'simple, scalar
variable'. Since $h is not a scalar variable, %$h is a syntax
error and the second form has to be used instead which is


when written in full. Since the semicolon can be omitted after the last
statement in a block, this can also be written as


It is usually more convenient to use the ->-dereferencing operator
instead of the 'block returning a reference' construct where possible,
eg (showing all three ways to get the value associated with 'a' in the
hash $h refers to):

[rw@sable]~#perl -e '$h = { a => 3 }; print(join(", ", $$h, $, $h->), "\n")'
3, 3, 3

Re: copy "sub" hash?

On 05/27/2014 05:29 AM, Rainer Weikusat wrote:
Quoted text here. Click to load it

Well, that was directly copied from the error message generated when I  
ran the code shown and I would expect the same message to show up for  
the OP if they ran the same code. Which is why.... well you catch my drift.

Quoted text here. Click to load it

Yes, I was thinking about other cases, but in this case they are. I  
didn't catch that as I tend to use them all the time in dereferencing  


Re: copy "sub" hash?

Quoted text here. Click to load it

Except that, as I already wrote, the reference isn't copied: It is
stringified and the result of that is used as a hash key (which will be
mapped to undef because nothing except the reference was provided on the
right-hand side of the assignment).  


Quoted text here. Click to load it

As I also already wrote: There's no relation between 'brackets' and
'dereferencing': A block returning a reference of an appropriate type
can be used instead of an ordinary identifier. That's a requirement in
case such a reference isn't simply stored in a scalar variable and it
isn't possible to use the 'infix dereference operator' (->)
instead. The latter should usually be preferred, cf (other posting by me
about this topic) /#!original/comp.lang.perl.misc/sF52WmASiJ0/m8NXDrQqj5wJ

Re: copy "sub" hash?

On 05/27/2014 08:52 AM, Rainer Weikusat wrote:
Quoted text here. Click to load it

Sigh.... I believe we're saying much the same thing, just with different  
spins. You are probably more technically correct given that I'm just a  
shade tree hacker and that's fine.

In my limited understanding the reference was not copied (correctly)  
since Perl does not implicitly dereference references. Given that all  
Perl arrays and hashes ONLY hold scalar values ( a string, number, or a  
reference), and the OP tried to assign that single internal scalar  
(reference pointer) to a hash, Perl said:

'Reference found where even-sized list expected'

Works for me.

Quoted text here. Click to load it

Whatever, but I think I'll continue to go with the approach shown in

"If you want to get at the thing a reference is referring to, then you  
have to do this yourself using either prefix typing indicators, like  
$ , @ , @ , or else postfix pointer arrows,  
like $a->[3] , $h-> , or even $ob->method()->[3] ."

Again, works for me and I don't really care if there are technical  
quibbles. Life is too short.

I DO appreciate your comments though, they make me at least think about  
the box though not necessarily outside of it. :-)


Re: copy "sub" hash?

Quoted text here. Click to load it

The usual term for copying what some 'reference' (or pointer) refers to,
instead of copying the reference itself, would be 'deep copy' (as
opposed to 'shallow copy') but that's yet something completely

my %hash_of_hopelessness = (
                anger =>     { address => 'hell', zip => 'Ha!'},
                despair =>  { address => 'heller', zip => 'Ha!ler'},
                ragnaroek =>{ address => 'gone', zip => '?' });

my (%well_of_measles, %saubohne_des_verderbens);

# associate a copy of the reference anger refers to with fear
$well_of_measles = $hash_of_hopelessness;
$hash_of_hopelessness = 'damnation';

print($well_of_measles, "\n");

# make a deep copy of the hash despair points to
$well_of_measles = }};
$well_of_measles = 'Asterdam';

print($hash_of_hopelessness, "\n");

# copy the keys and values of the ragnaroek hash
%saubohne_des_verderbens = %};

print("$_ -> $saubohne_des_verderbens\n") for keys(%saubohne_des_verderbens);

# try to use a reference as hashkey
my %turn_of_the_stew;
$turn_of_the_stew} = {};

# key isn't a reference anymore
printf("%s, %s(!)\n", $_, ref($_)) for keys(%turn_of_the_stew);


Quoted text here. Click to load it

I figure you believe to have found some contradiction between a text
from the 'Perl data structures intro' tutorial and the perlref exceprt
you're apparently incorrectly ascribing to me but at least insofar I'm
concerned, I have no idea what this contradiction is suppse to be ...

Re: copy "sub" hash?

# ???!
$b = $a;

Re: copy "sub" hash?

On 27/05/14 02:32, wrote:
Quoted text here. Click to load it

Steve May has given you the right answer.  I'd just add that  
Data::Dumper is endlessly useful in situations like this.  I have a  
little program called "tryout" which consists of the basic Perl stuff  
for a simple program, and I then add in whatever I need below to try  
things out.  In your case I have  this

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

my %a = ('mary'=>
          {'address'=>11, 'zip'=>12},
          {'address'=>21, 'zip'=>22},

my %b = $a;
print Dumper( \%b );  # Dumper likes references
%b = %};
print Dumper( \%b );

Other points: (1) try not to use $a and $b for lash-up variables.  They  
have specific meanings in the "sort" function and sooner or later the  
two usages will collide, with confusing results.  (2) Hash keys which  
have only numbers and letters don't need quotes, which saves a lot of  
typing.  See my example.  (3) I'm sure you have "use warnings" and "use  
strict" in your real program, don't you?


Henry Law            Manchester, England

Re: copy "sub" hash?

Quoted text here. Click to load it

You need the key, too, not just the value:

%b = (mary => $a);

(George's solution is equivalent if %b is empty. I leave it to you to
figure out what the difference is if %b is not empty)


   _  | Peter J. Holzer    | Fluch der elektronischen Textverarbeitung:
|_|_) |                    | Man feilt solange an seinen Text um, bis
| |   |         | die Satzbestandteile des Satzes nicht mehr
__/   | | zusammenpaƟt. -- Ralph Babel

Re: copy "sub" hash?

On 5/26/2014 6:32 PM, wrote:
Quoted text here. Click to load it

FYI, in case you missed mention of "deep copy" in this thread:

If you don't want sharing between the hashes, you'll need to clone  
rather than copy. If you just "copy" the reference ("shallow copy"),
changes in one hash will be mirrored in the other.

A simple example:

%b = %a;
$b = 'foo';  ##  $a changes too;

Whereas, with a  "deep copy":

use Storable qw(dclone);

my %b = %{ dclone(\%a) };
$b=12;       ## $a stays same

See:  perldoc -q recursive

Charles DeRykus

Re: copy "sub" hash?

On Mon, 26 May 2014 18:32:02 -0700 (PDT) wrote:  

c> how can you extract "mary" into another hash?
c> %a = ('mary'=>
c>          {'address'=>11, 'zip'=>12},
c>       'john'=>
c>          {'address'=>21, 'zip'=>22},
c>      );

c> %b = $a;  ???

Nothing to add to the great answers so far, except that the newly
released Perl 5.20.0 actually has this built-in, called a hash slice.
For a friendly summary, see


Site Timeline