> If you want a Hash which allows any kind of object as key, you have to declare it such:
> my $obj = Rutabaga.new; > my %vegeout{Any}; # <-- see: > https://docs.raku.org/language/hashmap#Non-string_keys_(object_hash) That's an interesting detail, I didn't get that that behavior wasn't the default. Thanks much. On 4/5/20, Tobias Boege <t...@taboege.de> wrote: > On Sun, 05 Apr 2020, Joseph Brenner wrote: >> I find in Raku that (as expected) I can use an object as a hash key: >> >> class Rutabaga { method color { say "purple (and white)"; } } >> >> my $obj = Rutabaga.new >> my %vegeout; >> %vegeout{ $obj } = "this works"; >> >> And for something I was doing I wanted to save up >> data about matches for various different regexs, >> so I thought I could just use a hash for this, like so: >> >> my (%match_locs, $loc); >> >> my $godzilla_rx = rx:i{ << godzilla >> }; >> if $text ~~ m/$godzilla_rx/ { >> $loc = $/.from; >> say "Godzilla: Found at $loc!"; >> %match_locs{ $godzilla_rx } = $loc; >> } >> >> But using a regex object as a hash key evidently doesn't work, >> it gives you the warning message: >> >> # Regex object coerced to string (please use .gist or .perl to do >> that) >> >> And what's worse is it coerces to an *empty list* which means *every* >> regex is treated as the same key. >> >> If you I follow the advice to use the *.perl, then that works, of course: >> >> %match_locs{ $godzilla_rx.perl } = $loc; >> >> But you wouldn't be able to use the keys of the hash as a regex >> object later, which seems sub-optimal, though not a concern for >> my present purposes. > > The same thing happened with your Rutabaga object. It had a default > Str method that was called when you used it as a hash key. It didn't > really store the object in the key but just its .Str: > > %vegeout.keys.any ~~ Rutabaga; # OUTPUT: «False» > %vegeout.keys.all ~~ Str; # OUTPUT: «True» > %vegeout.keys[0] === $obj; # OUTPUT: «False» > > This is because Hash objects, by default, have Str(Any) keys, meaning > Str and coercing when required. If you want a Hash which allows any > kind of object as key, you have to declare it such: > > my $obj = Rutabaga.new; > my %vegeout{Any}; # <-- see: > https://docs.raku.org/language/hashmap#Non-string_keys_(object_hash) > %vegeout{$obj} = "this works"; > %vegeout.keys.all ~~ Rutabaga; # OUTPUT: «True» > %vegeout.keys[0] === $obj; # OUTPUT: «True» > > This will also work with Regex objects. > > Regards, > Tobias > > -- > "There's an old saying: Don't change anything... ever!" -- Mr. Monk >