john bowring
john bowring

Reputation: 178

push hash onto array in perl, result defies understanding

Why does this..

my @menu;

my %el1 = ("element1" => "hello");
push @menu, \%el1;

my %el2 = ("element2" => "world");
push @menu, \%el2;

print to_json({"menu", @menu});

produce this..

{
    "menu": {
        "element1": "hello"
    },
    "HASH(0x18e2280)": null
}

and not this..

{
    "menu": {
        "element1": "hello",
        "element2": "world"
    }
}

Upvotes: 1

Views: 95

Answers (2)

Dave Cross
Dave Cross

Reputation: 69244

You have pushed two hash references onto @menu. So when you run this code:

print to_json({"menu", @menu});

It's exactly as if you ran:

print to_json({ "menu", \%el1, \%el2 });

The bit between { ... } is interpreted as a hash so the first and third items are seen as hash keys and the second item is seen as a value. So you get the output that you see. (And, as has been pointed out in comments, you would get a warning under use warnings as that second key has no associated value).

I think that what you wanted to write was:

print to_json({ "menu", \@menu });

But even that isn't right. You get the following:

{
    "menu":[{
        "element1":"hello"
    },{
        "element2":"world"
    }]
}

The two hashes that you added to the array are still quite separate.

But what you actually want is a single hash. So create that instead.

#!/usr/bin/perl

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

my @menu;

my %el1 = (
    "element1" => "hello",
    "element2" => "world",
);

print to_json({"menu", \%el1});

Upvotes: 4

toolic
toolic

Reputation: 62037

If you pass a reference to the array, the results are cleaner:

print to_json({"menu", \@menu});

Upvotes: 3

Related Questions