Ivan Wang
Ivan Wang

Reputation: 8445

Perl - assign a hash ref in a hash

use 5.010;
use strict;
use warnings;
use JSON::XS;
use YAML::XS;
my %data = ();
my $content = <<HERE;
{
  "name":"BLAHBLAH","contact":{"phone":"12345","twitter":"BLAHBLAH"},
  "location": {"address":"NOTTELLING","lat":10,"lng":10,"postalCode":"1234",
  "city":"BLAH","state":"BLAH","country":"BLAH"},
  "categories":[{"id":"BLAH","name":"BLAH"}]
}
HERE

my $id = "name1";

sub function {
    my ( $id, $data, $content ) = @_;
    my %data = %$data;
    my $out = decode_json($content);
    say "out:", Dump $out;
    $data{$id} = $out;
}

function( $id, \%data, $content );
say "data:", Dump %data;

This doesn't work as the way I expected. Can you please tell me why and how it will work?

Upvotes: 0

Views: 3872

Answers (3)

Dave Sherohman
Dave Sherohman

Reputation: 46225

The reason that you're not finding anything in the package-scoped %data (the one defined just after use YAML::XS) is because you're creating a brand-new and completely independent %data inside of function with the line

my %data = %$data;

This creates a new hash and copies the contents of the hash referenced by $data into it.

Try this instead:

sub function {
  my ($id, $data, $content) = @_;
  my $out = decode_json($content);
  say "out:", Dump $out;
  $data->{$id} = $out;
}

Upvotes: 3

wholerabbit
wholerabbit

Reputation: 11567

"This doesn't work as the way i expected."

What were you expecting? Let's step through the errors:

1) date != data

2) $content=~m!(,*)! will leave $1 empty, since $content doesn't contain any commas.

3) decode_json($1) will throw a runtime error, since $1 is empty and decode_json() can only be applied to a properly formatted JSON string.

4) $id is not defined.

"Can you please tell me why and how it will work?"

It won't work, if that isn't clear yet. There are more errors than code there.

"how do I assign a hash ref into hash?"

Use the \ unary reference operator, eg:

my %h = ();

my %h2 = (
    a => 10
);

$h{h2} = \%h2;

print $h{h2}->{a};  

You can also declare a scalar ($) as a reference to an anonymous (unnamed) hash; here $hr is a reference, the hash itself has no symbol or name associated with it:

my $hr = {
    n => 42
};

# as an existing hash member:

$h{h3} = {
    x => 666,
    # some other examples:
    hr => \%h2,
    hr2 => {
        x => 1024
    }    
};

Notice curly braces {} used in the declaration instead of (). When you are nesting (anonymous) hashes as with hr2, always use that form.

If you search for perl hash tutorial you'll find more in-depth things.

Upvotes: 4

Miguel Prz
Miguel Prz

Reputation: 13792

I think you have a typo:

function($id,/%data,$content);

must be

function($id,\%data,$content);

and $content is not a reference to %data hash, so in your function you should do:

my %data=%$data;  # in place of "my %content=%$content;"

Upvotes: 0

Related Questions