=begin pod

=head1 NAME

Hash::Agnostic - be a hash without knowing how

=head1 SYNOPSIS

=begin code :lang<raku>
use Hash::Agnostic;
class MyHash does Hash::Agnostic {
    method AT-KEY($key)          { ... }
    method keys()                { ... }
}

my %a is MyHash = a => 42, b => 666;
=end code

=head1 DESCRIPTION

This module makes an C<Hash::Agnostic> role available for those classes that
wish to implement the C<Associative> role as a C<Hash>.  It provides all of
the C<Hash> functionality while only needing to implement 2 methods:

=head2 Required Methods

=head3 method AT-KEY

=begin code :lang<raku>
method AT-KEY($key) { ... }  # simple case

method AT-KEY($key) { Proxy.new( FETCH => { ... }, STORE => { ... } }
=end code

Return the value at the given key in the hash.  Must return a C<Proxy> that
will assign to that key if you wish to allow for auto-vivification of elements
in your hash.

=head3 method keys

=begin code :lang<raku>
method keys() { ... }
=end code

Return the keys that currently exist in the hash, in any order that is
most convenient.

=head2 Optional Methods (provided by role)

You may implement these methods out of performance reasons yourself, but you
don't have to as an implementation is provided by this role.  They follow the
same semantics as the methods on the
L<Hash object|https://docs.raku.org/type/Hash>.

Methods in alphabetical order:
C<append>, C<ASSIGN-KEY>, C<elems>, C<end>, C<gist>, C<grab>, C<Hash>,
C<iterator>, C<kv>, C<list>, C<List>, C<new>, C<pairs>, C<push>,
C<raku>, C<Slip>, C<STORE>, C<Str>, C<values>

=head2 Optional Internal Methods (provided by role)

These methods may be implemented by the consumer for performance reasons
or to provide a given capability.

=head3 method BIND-KEY

=begin code :lang<raku>
method BIND-KEY($key, $value) { ... }
=end code

Bind the given value to the given key in the hash, and return the value.
Throws an error if not implemented.

=head3 method DELETE-KEY

=begin code :lang<raku>
method DELETE-KEY($key) { ... }
=end code

Remove the the given key from the hash and return its value if it existed
(otherwise return C<Nil>).  Throws an error if not implemented.

=head3 method EXISTS-KEY

=begin code :lang<raku>
method EXISTS-KEY($key) { ... }
=end code

Return C<Bool> indicating whether the key exists in the hash.  Will call
C<AT-KEY> and return C<True> if the returned value is defined.

=head3 method CLEAR

=begin code :lang<raku>
method CLEAR(--> Nil) { ... }
=end code

Reset the array to have no elements at all.  By default implemented by
repeatedly calling C<DELETE-KEY>, which will by all means, be very slow.
So it is a good idea to implement this method yourself.

=head1 AUTHOR

Elizabeth Mattijsen <liz@raku.rocks>

Source can be located at: https://codeberg.org/lizmat/Hash-Agnostic .
Comments and Pull Requests are welcome.

If you like this module, or what I’m doing more generally, committing to a
L<small sponsorship|https://github.com/sponsors/lizmat/>  would mean a great
deal to me!

=head1 COPYRIGHT AND LICENSE

Copyright 2018, 2020, 2023, 2024, 2025, 2026 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

=end pod

# vim: expandtab shiftwidth=4
