${{ foo => bar, baz => faz }}{ baz }

J

John Bokma

I noticed that the following works perfectly:

my $value = ${{ foo => bar, baz => faz }}{ $type }

which assigns bar when $type is foo, or faz when $type is baz.

Of course this is more fun when you have a longer list and don't want to
assign a hash to a variable and use it.

If there is a (tested!) shorter way to do this, let me know :)
 
U

Uri Guttman

JB> I noticed that the following works perfectly:
JB> my $value = ${{ foo => bar, baz => faz }}{ $type }

JB> which assigns bar when $type is foo, or faz when $type is baz.

JB> Of course this is more fun when you have a longer list and don't want to
JB> assign a hash to a variable and use it.

JB> If there is a (tested!) shorter way to do this, let me know :)

pretty much the same thing but using ->

{ foo => bar, baz => faz }->{ $type }

i have seen some cute hacks doing the same thing with array
refs. nothing that i would ever use in production. if the hash is ever
used more than one time it is a waste to build it each time through. if
it will always be used in the program (even once) it should be a static
hash declared and initialized outside the sub (or even in the sub but
named). i like dispatch tables and such but that style is too dense for
my taste. and if it ever grows beyond 2 entries it becomes very
fugly. also what about when $type isn't one of those two keys? if you
know it will always be one of them, you can reduce that to a simpler
conditional expression:

$type eq 'foo' ? 'bar' : 'faz' ;

even a 3 way choice is clean enough with conditionals:

$type eq 'foo' ? 'bar' :
$type eq 'baz' ? :'faz' : 'error' ;

damian conway has some wacky way he formats nested conditionals but i
can't recall it now.

also you didn't quote the values so that wasn't strict safe.

uri
 
G

gf

damian conway has some wacky way he formats nested conditionals but i
can't recall it now.

It's probably this, at least he showed something like it in the PBP
book.

my $a = 4;
my $x =
( $a == 1 ) ? 1
: ( $a == 2 ) ? 2
: ( $a == 3 ) ? 3
: 4;

It's pretty nice for big long lists that would otherwise be written as
chained if/then/elsif/else tests. What I like about it is it makes a
missing else condition turn into a syntax error which is caught at
compile-time instead of it being some latent run-time bug waiting to
sneak in.
 
J

John Bokma

Uri Guttman said:
JB> I noticed that the following works perfectly:
JB> my $value = ${{ foo => bar, baz => faz }}{ $type }

JB> which assigns bar when $type is foo, or faz when $type is baz.

JB> Of course this is more fun when you have a longer list and don't
want to JB> assign a hash to a variable and use it.

JB> If there is a (tested!) shorter way to do this, let me know :)

pretty much the same thing but using ->

{ foo => bar, baz => faz }->{ $type }

Thanks, that's the one I am looking for, I was quite sure there would be
a shorter version.
i have seen some cute hacks doing the same thing with array
refs. nothing that i would ever use in production. if the hash is ever
used more than one time it is a waste to build it each time through.
if it will always be used in the program (even once) it should be a
static hash declared and initialized outside the sub (or even in the
sub but named). i like dispatch tables and such but that style is too
dense for my taste. and if it ever grows beyond 2 entries it becomes
very fugly. also what about when $type isn't one of those two keys?

my $value = {



}->{ $type };
defined $value or die ...
if
you know it will always be one of them, you can reduce that to a
simpler conditional expression:

$type eq 'foo' ? 'bar' : 'faz' ;

Yup, I am aware of that one :)
even a 3 way choice is clean enough with conditionals:

$type eq 'foo' ? 'bar' :
$type eq 'baz' ? :'faz' : 'error' ;


But if you want one out of many? I don't like:

my $value =

( $type eq '...' ) ? '...'
: ( $type eq '...' ) ? '...'
:
damian conway has some wacky way he formats nested conditionals but i
can't recall it now.

I have Best Practices (Birthday present :) ), have to start reading in
it again.
also you didn't quote the values so that wasn't strict safe.

Yes, apologies for that.
 
M

Mons

my $value =

( $type eq '...' ) ? '...'
: ( $type eq '...' ) ? '...'
:
Using this way you must retype variable name ($type) again and again.
So it can't be shorter.
What about if this name is long (for ex: $myBigObjectName-
getObjectType ).
I think for the simple matching (equality) anonymous hash is the
shortest way (but in form of {...}->{...}, it's more clear ).
The only application of conditional statements is, I think, greater
perfomance, but it should be tested.
 
U

Uri Guttman

MD> As a side note, the above dereferencing syntax works with a single
MD> key, but not with multiple ones since

MD> }->{ $type1, $type2 }

MD> may actually mean two different things and Perl choose the IMHO less
MD> intuitive one. But maybe it was the most intuitive one when it was
MD> introduced.

that is a case of backward compatibility with perl4. multiple hash keys
in scalar context was used as a pseudo multilevel hash in perl4 (keys
are joined with $; into a single key. works if no key has $; inside
it). this still is the case in perl5 but is rarely used. the problem
with making it truly a slice is the multilevel problem. you can slice at
the bottom most level with no problem but what does it mean at higher
levels? you would need to create a deep data structure on the fly and it
couldn't be used for anything but returning it (via a ref). perl6 does
have this but it is consistant with lazy eval and other things. it would
be very odd in perl5 and a clunky special case.

uri
 
J

John Bokma

Mons said:
Using this way you must retype variable name ($type) again and again.

That's why I wrote

"But if you want one out of many? I don't like:"

above it, which you didn't quote.
The only application of conditional statements is, I think, greater
perfomance, but it should be tested.

Readability first, otherwise I wouldn't be programming in Perl as much as
I do now.
 
M

Michele Dondi

Hmmm, sounds like a convincing explanation. Hadn't tought of that, of
course.

Thinking of it better, the same problems affects $aref->[$n,$m],
although in that case there wasn't the same ambiguity. Given that
"multilevel" hashes are an obsolete feature anyway, and are obsoleted
exactly by real refs, then I would consider $href->{$foo,$bar} to be
more intuitively representing a slice. However inutitivity like
trea^Wbeauty is in the eye of the beholder...


Michele
 
U

Uri Guttman

MD> On Fri, 09 Mar 2007 18:19:15 +0100, Michele Dondi

MD> Thinking of it better, the same problems affects $aref->[$n,$m],
MD> although in that case there wasn't the same ambiguity. Given that
MD> "multilevel" hashes are an obsolete feature anyway, and are obsoleted
MD> exactly by real refs, then I would consider $href->{$foo,$bar} to be
MD> more intuitively representing a slice. However inutitivity like
MD> trea^Wbeauty is in the eye of the beholder...

it might work ok at the shallow top level there, but when you get deeper
is when it gets ugly and hard to manage. what does this return?

$href->{$foo,$bar}{qw( abc xyz )}

a reasonable guess would be a multilevel hash slice but that means
multiple internal loops, plenty of calls to malloc and such. some langs
(PL/I among them) supported such things. p5 didn't but p6 will. p6 even
allows a wildcard across a dimension.

uri
 
B

Bo Lindbergh

MD> Thinking of it better, the same problems affects $aref->[$n,$m],
MD> although in that case there wasn't the same ambiguity. Given that
MD> "multilevel" hashes are an obsolete feature anyway, and are obsoleted
MD> exactly by real refs, then I would consider $href->{$foo,$bar} to be
MD> more intuitively representing a slice. However inutitivity like
MD> trea^Wbeauty is in the eye of the beholder...

it might work ok at the shallow top level there, but when you get deeper
is when it gets ugly and hard to manage. what does this return?

$href->{$foo,$bar}{qw( abc xyz )}

a reasonable guess would be a multilevel hash slice but that means
multiple internal loops, plenty of calls to malloc and such.[/QUOTE]

No, a reasonable guess would be to do the same thing today's Perl does when
&$cref in the example below returns multiple values:

$cref->($foo)->{qw(abc xyz)}

(For the lazy: the function is called in scalar context, i.e. if it tries to
return multiple values only the last one is used.)


/Bo Lindbergh
 
M

Michele Dondi

it might work ok at the shallow top level there, but when you get deeper
is when it gets ugly and hard to manage. what does this return?

$href->{$foo,$bar}{qw( abc xyz )}

Well, what does this return?

$aref->[$foo,$bar][1..3]


Michele
 
U

Uri Guttman

[QUOTE="Uri Guttman said:
$href->{$foo,$bar}{qw( abc xyz )}

a reasonable guess would be a multilevel hash slice but that means
multiple internal loops, plenty of calls to malloc and such.
[/QUOTE]

BL> No, a reasonable guess would be to do the same thing today's Perl does when
BL> &$cref in the example below returns multiple values:

BL> $cref->($foo)->{qw(abc xyz)}

BL> (For the lazy: the function is called in scalar context, i.e. if
BL> it tries to return multiple values only the last one is used.)

and that is a function call and not a deep multilevel hash slice. apples
vs oranges.

uri
 
U

Uri Guttman

MD> Well, what does this return?

MD> $aref->[$foo,$bar][1..3]

my question was more rhetorical than real. my point is that the
semantics of deep slicing aren't clear (they took a while to hammer out
in p6). and if you did want the deep multilevel slicing to work it would
need complex semantics and implementation to handle all the
variations. the jump from p4 to p5 and adding refs and top level slices
was pretty big. adding multilevel slices maybe was too much for larry to
worry about and code. in any case the point in moot since p5 will never
have it.

uri
 
M

Michele Dondi

MD> Well, what does this return?

MD> $aref->[$foo,$bar][1..3]

my question was more rhetorical than real. my point is that the

Mine too.
semantics of deep slicing aren't clear (they took a while to hammer out
in p6). and if you did want the deep multilevel slicing to work it would
need complex semantics and implementation to handle all the

Mine, that it "shouldn't" be supported at all, just as with arrayrefs,
but thay top-level slicing would be more intuitive than the
pseudo-multidimensional interpretation. Of course we're discussing
even too much about these issues, since the situation is this and I
don't expect it to be changed. Only, I can't avoid asking myself why
that choice was made in the first place.


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top