=begin pod :kind("Type") :subkind("role") :category("metamodel")

=TITLE role Metamodel::AttributeContainer

=SUBTITLE Metaobject that can hold attributes

    role Metamodel::AttributeContainer {}

I<Warning>: this role is part of the Rakudo implementation, and is not
a part of the language specification.

Classes, roles and grammars can have attributes. Storage and introspection of
attributes is implemented by this role.

=head1 Methods

=head2 method add_attribute

    method add_attribute($obj, $attribute)

Adds an attribute. C<$attribute> must be an object that supports the
methods C<name>,  C<type> and C<package>, which are called without arguments.
It can for example be of L<type Attribute|/type/Attribute>.

=head2 method attributes

    method attributes($obj)

Returns a list of attributes. For most Raku types, these will be objects of
L<type Attribute|/type/Attribute>.

=head2 method set_rw

    method set_rw($obj)

Marks a type whose attributes default to having a write accessor. For example
in

    class Point is rw {
        has $.x;
        has $.y;
    }

The C<is rw> trait on the class calls the C<set_rw> method on the metaclass,
making all the attributes implicitly writable, so that you can write;

=begin code :preamble<class Point {}>
my $p = Point.new(x => 1, y => 2);
$p.x = 42;
=end code

=head2 method rw

    method rw($obj)

Returns a true value if L<method set_rw|#method set_rw> has been called on
this object, that is, if new public attributes are writable by default.

=begin comment

TODO: compose_attributes, get_attribute_for_usage

Also TODO: describe :local, :excl, :all options of method attributes

=end comment

=end pod
