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

Discussion in 'Perl Misc' started by John Bokma, Mar 8, 2007.

  1. John Bokma

    John Bokma Guest

    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 :)

    --
    John

    Dragons of a Fallen Sun
    http://johnbokma.com/mexit/2005/04/09/
    John Bokma, Mar 8, 2007
    #1
    1. Advertising

  2. John Bokma

    Uri Guttman Guest

    >>>>> "JB" == John Bokma <> writes:

    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 8, 2007
    #2
    1. Advertising

  3. John Bokma

    gf Guest

    On Mar 8, 3:14 pm, Uri Guttman <> wrote:

    > 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.
    gf, Mar 8, 2007
    #3
  4. John Bokma

    John Bokma Guest

    Uri Guttman <> wrote:

    >>>>>> "JB" == John Bokma <> writes:

    >
    > 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.

    --
    John

    CGI, templates, and bad Perl code
    http://johnbokma.com/mexit/2005/11/22/
    John Bokma, Mar 8, 2007
    #4
  5. John Bokma

    Mons Guest

    On Mar 9, 2:48 am, John Bokma <> wrote:
    >
    > 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.
    Mons, Mar 9, 2007
    #5
  6. John Bokma

    Uri Guttman Guest

    >>>>> "MD" == Michele Dondi <> writes:

    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 9, 2007
    #6
  7. John Bokma

    John Bokma Guest

    "Mons" <> wrote:

    > On Mar 9, 2:48 am, John Bokma <> wrote:
    >>
    >> my $value =
    >>
    >> ( $type eq '...' ) ? '...'
    >> : ( $type eq '...' ) ? '...'
    >> :
    >>

    > 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.

    --
    John

    Blue: out of the blue
    http://johnbokma.com/mexit/2005/01/06/
    John Bokma, Mar 10, 2007
    #7
  8. On Fri, 09 Mar 2007 18:19:15 +0100, Michele Dondi
    <> wrote:

    >>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

    >
    >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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Mar 10, 2007
    #8
  9. John Bokma

    Uri Guttman Guest

    >>>>> "MD" == Michele Dondi <> writes:

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

    >>> 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

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


    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 11, 2007
    #9
  10. John Bokma

    Bo Lindbergh Guest

    In article <>, Uri Guttman <>
    wrote:

    > >>>>> "MD" == Michele Dondi <> writes:

    >
    > 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.


    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
    Bo Lindbergh, Mar 12, 2007
    #10
  11. On Sun, 11 Mar 2007 18:38:54 -0500, Uri Guttman <>
    wrote:

    >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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Mar 12, 2007
    #11
  12. John Bokma

    Uri Guttman Guest

    >>>>> "BL" == Bo Lindbergh <> writes:

    BL> In article <>, Uri Guttman <>
    BL> wrote:

    >> $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.


    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 12, 2007
    #12
  13. John Bokma

    Uri Guttman Guest

    >>>>> "MD" == Michele Dondi <> writes:

    MD> On Sun, 11 Mar 2007 18:38:54 -0500, Uri Guttman <>
    MD> wrote:

    >> 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 )}


    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

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Mar 12, 2007
    #13
  14. On Mon, 12 Mar 2007 09:39:02 -0500, Uri Guttman <>
    wrote:

    > >> is when it gets ugly and hard to manage. what does this return?
    > >>
    > >> $href->{$foo,$bar}{qw( abc xyz )}

    >
    > 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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Mar 12, 2007
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jonathan Bartlett
    Replies:
    7
    Views:
    442
    Peter Nilsson
    Jul 8, 2005
  2. Wejn
    Replies:
    2
    Views:
    108
    Michal
    Nov 29, 2003
  3. Max Williams
    Replies:
    10
    Views:
    192
    Max Williams
    Dec 15, 2007
  4. Gunnar Hjalmarsson
    Replies:
    12
    Views:
    292
    Darren Dunham
    Feb 24, 2005
  5. J Krugman

    Is "require '/foo/bar/baz.pm'" portable?

    J Krugman, Apr 4, 2005, in forum: Perl Misc
    Replies:
    1
    Views:
    116
    Brian McCauley
    Apr 4, 2005
Loading...

Share This Page