Re: lvalue hash slice

2003-10-03 Thread A. Pagaltzis
* 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

2003-10-02 Thread Gaal Yahas
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

2003-10-01 Thread Tony Bowden
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

2003-09-30 Thread Gaal Yahas
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

2003-09-30 Thread Uri Guttman
 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

2003-09-30 Thread A. Pagaltzis
* 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

2003-09-30 Thread Gaal Yahas
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

2003-09-30 Thread Dave Mitchell
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

2003-09-30 Thread Ronald J Kimball
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

2003-09-30 Thread schwern
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

2003-09-30 Thread Jayaprakash Rudraraju
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!!