2

I have an array of hashes that I would like to convert into an un-named JSON array.

If I have an array of hashes which I then try to encode to JSON as such:

my @labs = ();  
push (@labs, {id=>'1', title=>'Lab1'});  
push (@labs, {id=>'2', title=>'Lab2'});  
my $json_text = to_json {\@labs}, {ascii=>1, pretty => 1};  

then the resulting JSON looks like:

{
   "ARRAY(0x358a18)" : null
}

when in fact I want it to look like:

[  
   {"title" : "Lab1", "id" : "1"},  
   {"title" : "Lab2", "id" : "2"}  
]  
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Try add a key, like `array` to the hash: `to_json ({array => \@labs}` or use as @MattJacob said: `to_json \@labs, {ascii=>1, pretty => 1}` – Håkon Hægland Oct 28 '15 at 14:53
  • lose the curly braces from around `\@labs` - they're converting the array into an object – Alnitak Oct 28 '15 at 14:55
  • 1
    Don't wrap your reference to `@labs` in an anonymous hash. – Matt Jacob Oct 28 '15 at 14:56
  • 2
    Please *always* `use strict` and `use warnings 'all'` at thje top of *every* Perl program you write. That code gives ***Odd number of elements in anonymous hash*** because of `{\@labs}` – Borodin Oct 28 '15 at 14:59

2 Answers2

7

Remove the curly braces from around \@labs - they're converting the array you've created into an anonymous hash before passing it to to_json:

#!/usr/bin/perl -w
use JSON -support_by_pp;
use strict;
my @labs = ();  
push (@labs, {id=>'1', title=>'Lab1'});  
push (@labs, {id=>'2', title=>'Lab2'});  
my $json_text = to_json \@labs, {ascii=>1, pretty => 1}; 
print $json_text;

output:

[
   {
      "title" : "Lab1",
      "id" : "1"
   },
   {
      "title" : "Lab2",
      "id" : "2"
   }
]
Alnitak
  • 334,560
  • 70
  • 407
  • 495
3

Your syntax is wrong, as you would have discovered if you had

use strict;
use warnings 'all';

at the top of your program. I must write that on Stack Overflow at least one a day, but still everyone thinks it doesn't apply to them

use strict;
use warnings 'all';
use v5.10.1;

use JSON;

my @labs;
push @labs, { id => 1, title => 'Lab1' };
push @labs, { id => 2, title => 'Lab2' };

say to_json \@labs, { ascii => 1, pretty => 1 };

output

[
   {
      "id" : 1,
      "title" : "Lab1"
   },
   {
      "id" : 2,
      "title" : "Lab2"
   }
]
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Do we have a canonical 'why should I use strict and warnings'? I suppose it's not really appropriate to close as a dupe... (although maybe, because it is sort of 'typographic error' level of close). – Sobrique Oct 28 '15 at 15:03
  • 2
    There's [**Why use strict and warnings?**](http://stackoverflow.com/questions/8023959/why-use-strict-and-warnings) but I'm not very fond of the answers. There's also [this from Perl Monks](http://www.perlmonks.org/?node_id=111088) and [this from Perl Maven](http://perlmaven.com/strict). I'm not interested in what people write in their own time, but it's definitely grounds for closure if a question is posted here that doesn't have strictures and warnings in place -- it's just gratuitously wasting people's time – Borodin Oct 28 '15 at 15:07
  • Also [this answer](http://stackoverflow.com/a/18065460/622310) is a high-quality discussion of a related question – Borodin Oct 28 '15 at 15:15
  • Thanks for the info regarding strict and warnings. I haven't touched perl in a very long time and am trying to make a few changes to an existing perl based web app. This will definitely help me to debug any issues in the future. – Vanyel Ashkevron Oct 28 '15 at 16:42
  • @VanyelAshkevron: It's a little tricky if your existing code doesn't have `use strict` in place. In that circumstance all undeclared variables are global package variables, which would be declared with `our` instead of `my`. If you `use strict` and start declaring variables then you may introduce bugs. If you add `use strict` and get lots of ***Global symbol requires explicit package name*** (which is Perl's legacy error message for an undeclared variable) then you should probably add `no strict 'vars'` as well rather than trying to declare stuff. You should be fine with `use warnings 'all'` – Borodin Oct 28 '15 at 16:55