How can I return a list of hashrefs from a map in Perl?

I have the following code mostly ok:

my $results = { data => [
   map {
      my $f = $_->TO_JSON;
      $f->{display_field} = $_->display_field($q);
      $f;
   } $rs->all
]};

      

Only I would prefer it to look like this:

my $results = { data => [
   map {
      %{$_->TO_JSON},
      display_field => $_->display_field($q),
   }, $rs->all
]};

      

But this gives a syntax error. How can I do what I want, or is my current version the best fit?

update : sorry for the extra semicolon. It's late here. Don't know how I missed it. Thanks guys!

+2


source to share


4 answers


It only gives a syntax error, because Perl thinks you need to omit the comma after map { ... }

it because it parses this map as a block, not an expression. Place it +

in front, it will fix it. Also, you cannot have a semicolon in an anonymous hash:



my $results = { data => [
   map +{
#      ^----------------- plus sign added
      %{$_->TO_JSON},
      display_field => $_->display_field($q);
#                                           ^---- should be comma or nothing
   }, $rs->all
]};

      

+7


source


The problem is that Perl doesn't look far ahead to figure out whether {

"run anonymous hash reference" or "run a block of code" means . He should (ideally) look at the appropriate one }

and see if there is a comma or not and act accordingly, but it is not. It looks a little ahead and tries to guess. And this time it's wrong and you get a syntax error about the comma that shouldn't be there, except that it shouldn't move it.

perldoc -f map

will tell you all about it. Basically, it says that if you put it +{

, Perl will understand that it means "not a block of code" and assume it is a hash reference. This is probably the reason for your syntax error. As another suggestion, one might say that map({ HASH STUFF }, $rs->all)

- I'm betting money, Perl won't guess that this is a code link here.

I couldn't get it to work, but without having $rs

either ->TO_JSON

or a variable named $q

, I couldn't get it to work in any way. Hope this helps. If not, write a little more code. Don't worry, we don't bite.



Also, while we're at it, why not write it like this:

my $results;
$results->{data} = [ map MAGIC MAP STUFF, $rs->all ];

      

It might be more readable, especially if you add a lot of things to $results

everything at once.

+3


source


I'm not really sure what kind of structure you are looking for. map

your first example already returns a list of hashrefs (each version $f

).

If you just want the syntax to be similar to your second example, you are almost right; you need to get rid of the extraneous semicolon in your map block and use a couple of curls to make the ref hash anonymous.

Something like:

my $results = { data => [
    map { { %{$_->TO_JSON},
            display_field => $_->display_field($q)
          }
    } $rs->all
]};

      

+1


source


I just always use the map in block form and structure the code to make it easy to parse. While you can put + in front of the opening to use the expression form, does it really matter to you?

Among other things, your first example looks great. Move on and solve real problems. :)

0


source







All Articles