Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

$var{'a',1,...}

by ady (Deacon)
on May 22, 2005 at 08:19 UTC ( [id://459315]=perlquestion: print w/replies, xml ) Need Help??

ady has asked for the wisdom of the Perl Monks concerning the following question:

hi
In my Perl 5 Desktop Ref. (Johan Vromans, O'Reilly) there's this statement:
$var{ 'a', 1, ... } emulates a multidimensional array
Could anyone pls. explain that construct ?
-- allan

Replies are listed 'Best First'.
Re: $var{'a',1,...}
by davido (Cardinal) on May 22, 2005 at 08:32 UTC

    Straight from the Camel's mouth:

    You can emulate a multidimensional hash by specifying more than one key within the braces, separated by commas. The listed keys are concatenated together, separated by the contents of $; ($SUBSCRIPT_SEPARATOR), which has a default value of chr(28). The resulting string is used as the actual key to the hash.

    I highly recommend the Camel book: Programming Perl, 3rd Edition, published by O'Reilly & Associates.

    And of course there is also the POD: perlvar:

    $;

    The subscript separator for multidimensional array emulation. If you refer to a hash element as

    $foo{$a,$b,$c}

    it really means

    $foo{join($;, $a, $b, $c)}

    But don't put

    @foo{$a,$b,$c} # a slice--note the @

    which means

    ($foo{$a},$foo{$b},$foo{$c})

    Default is "\034", the same as SUBSEP in awk. If your keys contain binary data there might not be any safe value for $; . (Mnemonic: comma (the syntactic subscript separator) is a semi-semicolon. Yeah, I know, it's pretty lame, but $, is already taken for something more important.)

    Consider using "real" multidimensional arrays as described in perllol.

    It's a syntax you just don't see that often. Most people who know about its existance are already so comfortable with complex datastructures built by using Perl's references that this syntax is set aside in favor of a more powerful tool.


    Dave

      Most people who know about its existance are already so comfortable with complex datastructures built by using Perl's references that this syntax is set aside in favor of a more powerful tool.
      It can be handy when dealing with large, sparse, data structures, where references would take too much memory.
Re: $var{'a',1,...}
by Roger (Parson) on May 22, 2005 at 08:35 UTC
    You should learn to use the Data::Dumper module to do your investigation. It is one of the most important perl modules.

    use Data::Dumper; $var{ 'a', 1, 'b', 2 } = 1; # ^ this statement builds a simple hash table, %var print Dumper(\%var);

    This shows that the above is really...
    $VAR1 = { 'a1b2' => 1 };

      Careful when using Data::Dumper to dump strings.

      use Data::Dumper; $h{"a", 1, "b", 2} = 1; $h{a1b2} = 2; print Dumper \%h;
      produces the counterintuitive:

      $VAR1 = { 'a1b2' => 2, 'a1b2' => 1 };

      But:

      use Data::Dumper; $h{"a", 1, "b", 2} = 1; $h{a1b2} = 2; $_ = Dumper \%h; s/(\P{IsPrint})/"\\x{".sprintf "%04x}", ord $1/ge; print
      reveals:
      $VAR1 = { 'a1b2' => 2, 'a\x{001c}1\x{001c}b\x{001c}2' => 1 };

      ("\x{001c}" eq "\034" eq chr(28) eq $; See first reply.)

Re: $var{'a',1,...}
by tlm (Prior) on May 22, 2005 at 13:36 UTC

    In addition to what davido posted, let me point out that "the space between the curlies" is a magical place, and exploring all its mysteries can lead to countless epiphanies.

    For example, there you will find an apparent violation of the Perl dogma that says that "a list can't exist in scalar context." The context between the curlies is a scalar context; this is why, for example, in the following DB interaction, the second line initializes $hash{ 3 }:

    DB<1> @subkeys = qw( foo bar baz ) DB<2> $hash{ @subkeys } = 5 DB<3> x \%hash 0 HASH(0x846a000) 3 => 5
    Now, in a scalar context, a comma-separated list should evaluate to the last member of the list. Therefore,
    $hash{ 'foo', 'bar', 'baz' } = 1;
    should amount to initializing $hash{ 'baz' }. Instead, it appears (to those who are not pure of soul) as though the comma-separated list survives long enough in this scalar context for it to be shellacked into a join( $;, LIST ) thingie.

    This apparent violation of dogma is resolved by declaring that the commas in $hash{ 'foo', 'bar', 'baz' } are not comma operators; they receive instead special syntactic dispensation from the Holy Interpreter (I'm sure there is a bull or two written on this somewhere).

    But the wonders don't end there. It is not just textual commas that receive a special dispensation, but also =>'s, and even the implicit commas in qw() expressions, which leads to great marvels such as

    DB<1> $s = qw( eenie meenie minie moe ) DB<2> p $s moe DB<3> $hash{ qw( eenie meenie minie moe ) } = 1234 DB<4> x \%hash 0 HASH(0x846a000) "eenie\c\meenie\c\minie\c\moe" => 1234
    I am sure one can derive hours of edifying meditation from variations of these examples.

    One last thing: the commas do not get in the way of the auto-quoting that happens inside the curlies. E.g. $hash{ 'foo', 'bar' } and $hash{ foo, bar } refer to the same thing.

    the lowliest monk

      Very interesting meditation here.

      One could consider this idiom "The Perl Way" in-a-nutshell, --- expanding the syntax of one fundamental datastruct (hash) to emulate another (MD array), and of course there's several ways to do that...

      This flexibility originating in a wish to make the language dance to the pipe of the programmer's needs & expectations, that's what makes it an effective an tool to use. And of course, --hours of fun to learn.

      "Ca, ce n'est pas une Pipe"

      -- allan
Re: $var{'a',1,...}
by ady (Deacon) on May 22, 2005 at 11:42 UTC
    Thanks davido && Roger!

    That shortcut was a real AHA-experience for me... but very much in the spirit of Perl of course. Rather smart actually! for a quick MD-array, though i do see your pt. Dave vith resp. to using refs. for building up complex datastructs. for larger apps. I agree on that.
    I did read (ride) the Camel; -- some months back by now, so i didn'n recognize the construct, tho' i must have seen it there. -- Much stuff crammed into that big hump :)
    I didn't think of using Data::Dumper to clearify exactly what this construct might map to in terms of Perl internal dstructs (tho' i've used it in other contexts). But yes, i do see now, how that could have resolved the issue!

    Thanks' to both of you, -- yet another idiom in the bag (almost like collecting butterflies...
    best regards -- allan

    ===========================================================
    As the eternal tranquility of Truth reveals itself to us, this very place is the Land of Lotuses
    -- Hakuin Ekaku Zenji
Re: $var{'a',1,...}
by tphyahoo (Vicar) on May 23, 2005 at 08:28 UTC
    $; has a ...
    "default value of chr(28)" Default is "\034", the same as SUBSEP in awk.
    Which is it? Or am I overlooking something obvious?

      You are overlooking something obvious :-)

      perl -wle '$c = chr(28); $d = "\034";print $c eq $d ? "true" : "false" +' true

      cheers

      thinker

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://459315]
Approved by davido
Front-paged by Thilosophy
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-03-19 08:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found