Perl Hash PMC

Synopsis

new P0, .PerlHash     # PMC creation

set P0["foo"], "bar"  # $P0{foo} = "bar"
set S0, P0["foo"]     # $S0 = $P0{foo}

delete P0["foo"]      # delete($P0{foo})

exists I0, P0["zbr"]  # $I0 = exists($P0{zbr})
defined I0, P0["zbr"] # $I0 = defined($P0{zbr})

clone P1, P0          # clone PMC

Creation

As with other PMC's, create the hash with

new P0, .PerlHash

Accessing Elements

To store elements on the hash use

set P0["key"], "value"

Note that you can use registers in the same way:

new P0, .PerlHash
set S0, "one"
set S1, "two"
set P0[S0], 1     # $P0{one} = 1
set P0[S1], 2     # $P0{two} = 2

To get the element use it in the opposite way:

set I1, P0["one"]   # $I1 = $P0{one}

Notice that a hash is polymorphic on the value it holds.

When using a key that does not exist in the hash, the value returned depends on the register used to retrieve the element.

set I0, P1["qwerty"]  # I0 = 0
set N0, P1["qwerty"]  # N0 = 0.000
set S0, P1["qwerty"]  # S0 = ""
set P0, P1["qwerty"]  # typeof(P0) = PerlUndef

You can check if an hash element exists before accessing it, using the exists command:

exists I0, P0["a"]

This example will set the value one in register I0 if the key exists, the value zero if it does not exist.

Notice that this tests if there is anything. In fact, the exists command will return true if the element in that position is a PerlUndef PMC. To check if that element is defined, use the defined command:

defined I0, P0["a"]

TODO: Steve Fink said:

And if there were a keys() method, then 'defined' and 'exists' are
very different. (And there ought to be, and would be if we weren't
all ignoring Leo's iterator proposal.)

I need to read that proposal :-)

Removing Elements

You can remove (or delete) an element from the hash using the delete command:

delete P0["a"]

This means that:

new P0, .PerlHash
set P0["a"], 2
delete P0["a"]
exists I0, P0["a"]

will put the value zero on register I0.

Size of the Hash

To get the number of keys (size of the hash) use

set I0, P0

where P0 is the Perl Hash PMC and I0 the register where to store the hash size. You can use an Perl Hash PMC on an if or unless command, where it will be checked for the number of elements.

Cloning

As other PMCs, you can clone Perl hashes. If you try something like

new P0, .PerlHash
set P0["a"], 1
set P0["b"], 2

clone P1, P0

P1 is a copy of P0, where you can do whatever you want without changing the other hash.

TODO: deep or shallow copy? Apparently, deep... wait untill there are news!

TODO

- Compound keys