Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

||= in Hash Slice

by Brovnik (Hermit)
on Jan 06, 2009 at 11:48 UTC ( [id://734413]=perlquestion: print w/replies, xml ) Need Help??

Brovnik has asked for the wisdom of the Perl Monks concerning the following question:

I want to do some hash slice assigns.
my $key_fields = [ qw( trade_ref sec_code lot of other fields ) ]; my $copy_fields = [ qw( item_period other fields) ]; my $audit = {}; @{$audit}{@$key_fields} = @{$item}{@$key_fields}; # $item is a hashref with some but maybe not all of the # above fields defined $audit->{$_} = $item->{$_} || '' for @$copy_fields;
Alternatively :
@{$audit}{@$copy_fields} = @{$item}{@$copy_fields}; $audit->{$_} ||= '' for @$copy_fields;
These work, but I really want to do :
@{$audit}{@$copy_fields} = @{$item}{@$copy_fields} || '';
to make sure there are no undefs. Can I do the above as a single Hash slice assignment ?

Replies are listed 'Best First'.
Re: ||= in Hash Slice
by ikegami (Patriarch) on Jan 06, 2009 at 12:40 UTC

    Three ways:

    @{$audit}{@$copy_fields} = map $_ || '', @{$item}{@$copy_fields};
    $_ ||= '' for @{$audit}{@$copy_fields} = @{$item}{@$copy_fields};
    no warnings 'uninitialized';

    I only recommend the first.

Re: ||= in Hash Slice
by Corion (Patriarch) on Jan 06, 2009 at 12:00 UTC

    I'm not aware of a convenient per-item combination. I hear that Perl 6 will have "hyper-operators" for that, when it reaches a stable release version >= 1.0.

    I'd do that with a map, as I always use map when transforming one list into another:

    @{$audit}{@$copy_fields} = map { defined $item->{$_} ? $item->{$_} : ' +' } @$copy_fields;

    Your code will happily replace a value of "0" by "", and I guess that's not intended.

      Yup, I guess that works, but I was hoping for something a bit more elegant.
      @{$audit}{@$copy_fields} = map { $item->{$_} || '' } @$copy_fields;
      Is probably the nearest I'll get.
      P.S. The '' vs. 0 difference is irrelevant here in my case, I just want avoid undefs.
        That may not, probably won't, work in all cases ... consider when the value of $item->{$_} is 0: in this case, the wanted value of 0 will be overwritten by the empty string, since $item->{$_} is, from a perl POV, false. Hence Corions suggestion, tho' not quite what you were seeking, is better.

        A user level that continues to overstate my experience :-))
Re: ||= in Hash Slice
by gone2015 (Deacon) on Jan 06, 2009 at 12:08 UTC

    I don't think so. But this should work:

    @{$audit}{@$copy_fields} = map { defined($_) ? $_ : '' } @{$item}{@$ +copy_fields} ;
      $_ here is the key, which will always be defined, so the defined($item->{$_}) as above is needed.
      Edit: Oops, misread the reply, apologies.
        No it's not. It's the value.
Re: ||= in Hash Slice
by JavaFan (Canon) on Jan 06, 2009 at 12:33 UTC
    Can I do the above as a single Hash slice assignment ?
    No. The problem is the '||' operator which provides scalar context to its LHS argument.

    You'll have to type 'map' if you want a map... ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://734413]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2025-06-13 19:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.