On Thu, Oct 02, 2003 at 09:39:53PM -0000, [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/

Reply via email to