Using a hash with object keys in Perl 6

前端 未结 2 1079
旧巷少年郎
旧巷少年郎 2021-01-19 06:02

I\'m trying to make a Hash with non-string keys, in my case arrays or lists.

> my %sum := :{(1, 3, 5) => 9,         


        
2条回答
  •  半阙折子戏
    2021-01-19 06:42

    Elizabeth's answer is solid, but until that feature is created, I don't see why you can't create a Key class to use as the hash key, which will have an explicit hash function which is based on its values rather than its location in memory. This hash function, used for both placement in the list and equality testing, is .WHICH. This function must return an ObjAt object, which is basically just a string.

    class Key does Positional {
      has Int @.list handles ;
      method new(*@list) { self.bless(:@list); }
      method WHICH() { ObjAt.new(@!list.join('|')); }
    }
    
    my %hsh{Key};
    %hsh{Key.new(1, 3)} = 'result';
    say %hsh{Key.new(1, 3)}; # output: result
    

    Note that I only allowed the key to contain Int. This is an easy way of being fairly confident no element's string value contains the '|' character, which could make two keys look the same despite having different elements. However, this is not hardened against naughty users--4 but role :: { method Str() { '|' } } is an Int that stringifies to the illegal value. You can make the code stronger if you use .WHICH recursively, but I'll leave that as an exercise.

    This Key class is also a little fancier than you strictly need. It would be enough to have a @.list member and define .WHICH. I defined AT-POS and friends so the Key can be indexed, pushed to, and otherwise treated as an Array.

提交回复
热议问题