Search code examples
objecthashproxyraku

Proxy object for a hash?


How can I make a Proxy object for a hash? I can't seem to find a way to pass in the hash key:

#sub attr() is rw {
sub attr($name) is rw {
  my %hash;
  Proxy.new(
    FETCH => method (Str $name) { %hash«$name» },
    STORE => method (Str $name, $value) { %hash«$name» = $value }
  );
}

my $attr := attr();
$attr.bar = 'baz';
say $attr.bar;

Solution

  • A Proxy is a substitute for a singular container aka Scalar. A Hash is a plural container where each element is a Pair, with, by default, a Scalar for the value of the pair.

    A possible solution (based on How to add subscripts to my custom Class in Raku?) is to delegate implementation of Associative to an internal hash but override the AT-KEY method to replace the default Scalar with a Proxy:

    class ProxyHash does Associative {
    
      has %!hash handles
        <EXISTS-KEY DELETE-KEY push iterator list kv keys values gist Str>;
    
      multi method AT-KEY ($key) is rw {
        my $current-value := %!hash{$key};
        Proxy.new:
          FETCH => method ()       { $current-value },
          STORE => method ($value) { $current-value = $value }
      }
    }
    
    my %hash is ProxyHash;
    %hash<foo> = 42;
    say %hash; # {foo => 42}