Re: lvalue hash slice
* Gaal Yahas [EMAIL PROTECTED] [2003-10-03 11:24]: Two points about this. First, the lvalue ?: is kinda, uh, Perlish to the extreme. Yeah. It tends to be a powerful obfuscant too. I had to look thrice at your code (then went oh, duh!). For more than two or maybe three lvalues to switch between, I avoid it. And second, of course after I'd looked at it again it became clear it could be refactored to be even more succinct. If I'm willing to leave sortorder inside the frgrp structure[*], this can easily be remade: for (keys %$res) { $frgrp{$1}{$2} = $res-{$_} if /^frgrp_(\d+)_(name|public|sortorder)$/; $friend{$1}{$2} = $res-{$_} if /^friend_(\d+)_(user|name|groupmask|type)$/; } Might be overkill in this case, but honouring capture similarities in code, differences in data, I might be inclined to write this along the lines of my %parse_type_for = ( frgrp = [ \%frgrp, 'name|public|sortorder' ], friend = [ \%friend, 'user|name|groupmask|type' ], ); for (keys %$res) { my ($name) = /^([^_]+)/; my ($type, $options) = @{$parse_type_for{$key}} or next; /^$name_(\d+)_($options)$/g and $type-{$1}{$2} = $res-{$key}; } I'm not happy with the name choice for ``$type'', but couldn't think of a better term. -- Regards, Aristotle If you can't laugh at yourself, you don't take life seriously enough.
Re: lvalue hash slice
On Thu, Oct 02, 2003 at 09:39:53PM -, [EMAIL PROTECTED] wrote: Has this always worked? I coulda sworn I tried it in the past with no luck... It has always worked since I started Perl (sometime around 5.4). I'd make an educated guess that it has been available at least as long as C(LIST)[EMAIL PROTECTED] has. That would mean at least ever since Perl5; likely as early as Perl4. Oh well. I think I started around when 5.003 was all new, but so was I; I guess my attempts were just ungrammatical then and ever since I had assumend this just doesn't work. Okay, score down for solution, score up for obfuscation...! :p Why obfuscation? Hash slice as lvalue is extremly elegant and *very* readable in my opinion. It requires very little verbiage and communicates the intent clearly. Oh, I didn't mean that lvalue hash slices are an obfuscation. Just that my unneccessary workaround for their alleged lack of existence was. I agree they are a very elegant concept: that's why I was looking for a workaround in the first place. For me, Perl's extremly expressive data structure access syntax and its ability to operate on lists without the programmer having to explicitly iterate is pretty much the main selling point of the language. I *very* much miss it when I try to work with machine oriented languages. If I had a nickel for every time I've written for (i = 0; i N; i++) in C I'd be a millionaire. -- Michael Vanier Yeah. To cheer myself up from the embarassment of the original post, I dug up some old code of mine. For context, it takes a LiveJournal protocol response, which is basically a flattened data structure, and rearranges it into a clearer and probably more useful deep structure: (The number is an id to which this item refers. On the wire, results travel as key\nvalue; that is trivially converted to a hash.) foreach (keys %$res) { /frgrp_(\d+)_name/ ? $frgrp{$1}{name} : /frgrp_(\d+)_public/? $frgrp{$1}{public} : /frgrp_(\d+)_sortorder/ ? $grpord{$1} : /frgrp_maxnum/ ? $maxnum : /friend_(\d+)_user/ ? $friend{$1}{user} : /friend_(\d+)_name/ ? $friend{$1}{name} : /friend_(\d+)_groupmask/? $friend{$1}{groupmask} : /friend_(\d+)_type/ ? $friend{$1}{type} : undef = $res-{$_} : } Two points about this. First, the lvalue ?: is kinda, uh, Perlish to the extreme. And second, of course after I'd looked at it again it became clear it could be refactored to be even more succinct. If I'm willing to leave sortorder inside the frgrp structure[*], this can easily be remade: for (keys %$res) { $frgrp{$1}{$2} = $res-{$_} if /^frgrp_(\d+)_(name|public|sortorder)$/; $friend{$1}{$2} = $res-{$_} if /^friend_(\d+)_(user|name|groupmask|type)$/; } And one line shorter if I'm willing to unstrict for a while or if I can live with a deeper structure. [*] As for sorting frgrps, that would then of course be made @sorted_ids = sort { $frgrp{$a}{sortorder} = $frgrp{$b}{sortorder} } keys %frgrp; ...or @sorted_frgrps = map { $frgrp-{$_} } sort ... Oh, and maxnum can actually be ignored in all this. It's mostly there for c implementations anyway, that want to know how much memory to allocate in advance. -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: lvalue hash slice
On Tue, Sep 30, 2003 at 11:11:17PM +0100, Dave Mitchell wrote: (I tried it on Perl 1.0.15, but unfortunately it didn't like it. I even managed to get it to coredump. Perhaps I should submit a bug report? :-) Well, Schwern is theoretically maintaining the 1.x track, so you probably should :) Tony
lvalue hash slice
I like hash slices: ($one, $two, $three) = @hash{ qw/aaa bbb ccc/ }; Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG But this does: push @values, reverse @keys; $hash{ $values[$#values - $_] } = $values[$_] for 0 .. @values / 2 - 1; $#values /= 2; -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: lvalue hash slice
GY == Gaal Yahas [EMAIL PROTECTED] writes: GY I like hash slices: GY ($one, $two, $three) = @hash{ qw/aaa bbb ccc/ }; GY Sadly, this doesn't work as an lvalue: GY @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG works fine for me. perl -le '@h{ qw/aaa bbb/ }= (3, 5);print join ,, values %h' 5,3 where did you get the notion that hash slices won't work as an lvalue? any list (of lvalues) can be an lvalue and a slice is just syntactic sugar for the same list expanded out. uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs http://jobs.perl.org Damian Conway Class in Boston - Sept 2003 -- http://www.stemsystems.com/class
Re: lvalue hash slice
* Gaal Yahas [EMAIL PROTECTED] [2003-09-30 20:14]: Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three); I use that *all* the time. The problem is not with Perl here.. -- Regards, Aristotle If you can't laugh at yourself, you don't take life seriously enough.
Re: lvalue hash slice
On Tue, Sep 30, 2003 at 08:12:54PM -, I wrote: Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG And evidently it does! Oops! :) Has this always worked? I coulda sworn I tried it in the past with no luck... Okay, score down for solution, score up for obfuscation...! :p -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: lvalue hash slice
On Tue, Sep 30, 2003 at 11:53:01PM +0300, Gaal Yahas wrote: On Tue, Sep 30, 2003 at 08:12:54PM -, I wrote: Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG And evidently it does! Oops! :) Has this always worked? I coulda sworn I tried it in the past with no luck... Since at least 5.003_22, and probably well before then: $ perl5.3.22 -e '@h{a,b} = (1,2); print @h{a,b}, \n;' 12 (I tried it on Perl 1.0.15, but unfortunately it didn't like it. I even managed to get it to coredump. Perhaps I should submit a bug report? :-) -- Strange women lying in ponds distributing swords is no basis for a system of government. Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony. Dennis - Monty Python and the Holy Grail.
Re: lvalue hash slice
On Tue, Sep 30, 2003 at 11:07:24PM +0300, Gaal Yahas wrote: I like hash slices: ($one, $two, $three) = @hash{ qw/aaa bbb ccc/ }; Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG That actually does work. Ronald
Re: lvalue hash slice
On Tue, Sep 30, 2003 at 11:07:24PM +0300, Gaal Yahas wrote: I like hash slices: ($one, $two, $three) = @hash{ qw/aaa bbb ccc/ }; Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG It doesn't? $ perl -wle '$one=1; $two=2; $three=3; @h{qw(a b c)} = ($one,$two,$three); print %h' c3a1b2
Re: lvalue hash slice
1:32pm, IP packets from [EMAIL PROTECTED] delivered: On Tue, Sep 30, 2003 at 11:07:24PM +0300, Gaal Yahas wrote: I like hash slices: ($one, $two, $three) = @hash{ qw/aaa bbb ccc/ }; Sadly, this doesn't work as an lvalue: @hash{ qw/aaa bbb ccc/ } = ($one, $two, $three);# WRONG It doesn't? $ perl -wle '$one=1; $two=2; $three=3; @h{qw(a b c)} = ($one,$two,$three); print %h' c3a1b2 You cannot print hash, like you can print a list. Because elements in the hash are stored differently to optimize retrieval of hash elements. -- Off the keyboard, over the bridge, past the hub, thru the router, down the line, nothing but net!!