[Melbourne-pm] Nested maps returning hash references

Alfie John alfiejohn at gmail.com
Wed Oct 5 03:51:47 PDT 2011


Hey Myf,

On Wed, Oct 5, 2011 at 9:03 PM, Myf White <myfwhite at gmail.com> wrote:
> The + was missing in your previous email. I put it in here and it worked as
> advertised:
> map {
>      my $f = $_;
>      +{     #<<<<<<<<<<<<<<<<<<--- HERE
>           map {
>                $f->can($_) ? ( $_ => $f->$_() ) : ()
>           } @fields
>      }
> } @foos

lol. I copied the wrong version. Yep, that's where it should have been.

> On Wed, Oct 5, 2011 at 7:42 PM, Alfie John <alfiejohn at gmail.com> wrote:
>>
>> Also, you could have reduced it down by returning a hashref on the
>> truth side of the ternary:
>>
>>  map {
>>    my $f = $_;
>>    map {
>>      $f->can($_) ? { $_ => $f->$_ } : ()
>>    } qw( label name html )
>>  } @fields
>
> Pretty sure this wouldn't work. A hashref can't be assigned as the key of
> another hashref (well technically it can but it's not very useful - I think
> it would just stringify to HASHgobbledigook).

I just ran it and it gives me what I want. I think the reason for your
thinking is that you do:

  my %hash = map { do_stuff() };

But you can also do:

  my @array = map { do_stuff() };

Since do_stuff() here is returning a hashref each time, @array ends up
as an array of hashes (which is what Toby needs).

Alfie

>
>>
>> It's a shame you can't access hidden scopes and you need to create a
>> temporary variable like $f here. Maybe Perl needs a way of accessing
>> outer block values e.g.:
>>
>>  map {
>>    map {
>>      $_^->can($_) ? { $_ => $_^->$_ } : ()
>>    }
>>  } @fields
>>
>> The $_^ is $_ but one level higher (e.g. git's HEAD^ vs HEAD). But
>> since having multiple levels would look ugly (e.g. $_^^^ for 3 levels
>> out, maybe we also need a postfix operator like $_@ which is an array
>> containing the all of the $_ values for each level:
>>
>>  $_@ = ( $_, $_^, $_^^, $_^^^ );
>>
>> But this wouldn't just be for $_, it would work on all variables. That
>> way, when you local a variable, you can still access the hidden values
>> too. Perl already stores their values.
>>
>> Thoughts?
>>
>> Alfie
>
> Because Perl really needs more special variables so that we don't have to
> bother naming anything ourselves.
>
>>
>> On Wed, Oct 5, 2011 at 7:24 PM, Alfie John <alfiejohn at gmail.com> wrote:
>> > Sorry... read my email during dinner.
>> >
>> > Here is what I did as a test:
>> >
>> >  #!/usr/bin/perl;
>> >
>> >  use warnings;
>> >  use strict;
>> >
>> >  package Foo;
>> >
>> >  use base 'Class::Accessor';
>> >
>> >  my @fields = qw{ label name html };
>> >  Foo->mk_accessors( @fields );
>> >
>> >  sub new {
>> >    my $self = bless {}, $_[0];
>> >
>> >    foreach my $field ( @fields ) {
>> >            $self->$field( $field );
>> >    }
>> >
>> >    return $self;
>> >  }
>> >
>> >  my @foos = map { Foo->new() } 1..3;
>> >
>> >  use Data::Dumper; warn Dumper([
>> >          map {
>> >                  my $f = $_;
>> >                  {
>> >                          map {
>> >                                  $f->can($_) ? ( $_ => $f->$_() ) : ()
>> >                          } @fields
>> >                  }
>> >          } @foos
>> >  ]);
>> >
>> > It looks essentially the same as what you were running. This should
>> > output:
>> >
>> > $VAR1 = [
>> >          {
>> >            'html' => 'html',
>> >            'name' => 'name',
>> >            'label' => 'label'
>> >          },
>> >          {
>> >            'html' => 'html',
>> >            'name' => 'name',
>> >            'label' => 'label'
>> >          },
>> >          {
>> >            'html' => 'html',
>> >            'name' => 'name',
>> >            'label' => 'label'
>> >          }
>> >        ];
>> >
>> > Take out the + and you get:
>> >
>> > $VAR1 = [
>> >          'label',
>> >          'label',
>> >          'name',
>> >          'name',
>> >          'html',
>> >          'html',
>> >          'label',
>> >          'label',
>> >          'name',
>> >          'name',
>> >          'html',
>> >          'html',
>> >          'label',
>> >          'label',
>> >          'name',
>> >          'name',
>> >          'html',
>> >          'html'
>> >        ];
>> >
>> > After looking at yours, it looks like the problem was the trailing
>> > semi colon after the qw[} :)
>> >
>> > Alfie
>> >
>> > On Wed, Oct 5, 2011 at 5:44 PM, Toby Corkindale
>> > <toby.corkindale at strategicdata.com.au> wrote:
>> >>
>> >> On 05/10/11 17:38, Alfie John wrote:
>> >>>
>> >>> Whoops. That qw{} was in my test code.
>> >>>
>> >>> I added the + on the block and it worked for me.
>> >>
>> >> That is weird; I tried prefixing a + symbol to both the
>> >> left-hand-curly-braces in the maps (one at a time), to no avail!
>> >>
>> >> This is Perl 5.14.1..
>> >
>> _______________________________________________
>> Melbourne-pm mailing list
>> Melbourne-pm at pm.org
>> http://mail.pm.org/mailman/listinfo/melbourne-pm
>
>


More information about the Melbourne-pm mailing list