Rules / Types, classes & roles / metamodel

Metamodel::Mixins Reference

Metaobject for generating mixins

What it is #

Position in the hierarchy #

Inherits from
Does
Consumed byMetamodel::ClassHOW, Metamodel::EnumHOW

Routines #

Signatures are reproduced from the documentation, including their declared return types. A routine listed here is part of the type's published interface; whether Raku++ implements it is a separate question, answered by the examples below.

method set_is_mixin #

method set_is_mixin($obj)

Marks $obj as being a mixin.

method is_mixin #

method is_mixin($obj)

Returns 1 If $obj has been marked as being a mixin with set_is_mixin, otherwise returns 0.

method set_mixin_attribute #

method set_mixin_attribute($obj, $attr)

Sets the mixin attribute for $obj to $attr (which should be an Attribute instance).

method mixin_attribute #

method mixin_attribute($obj)

Returns the mixin attribute for $obj set with set_mixin_attribute.

method setup_mixin_cache #

method setup_mixin_cache($obj)

Sets up caching of mixins for $obj. After this metamethod has been called, calls to mixin will not create a new type for mixins of $obj given the same list of roles more than once. This should be called at some point before composition.

method flush_cache #

method flush_cache($obj)

No-op.

method generate_mixin #

method generate_mixin($obj, @roles)

Creates a new mixin metaobject that inherits from $obj and does each of the roles in @roles. This is then composed and has its mixin attribute set (if any exists) before getting returned. While this generates a new mixin type, this doesn't actually mix it into $obj; if that is what you intend to do, use the mixin metamethod instead.

method mixin #

method mixin($obj, *@roles, :$needs-mixin-attribute)

Generates a new mixin type by calling generate_mixin with $obj and @roles. If $obj is composed, the mixin cache of $obj will be checked for any existing mixin for these beforehand. If $obj is an instance of a type, this will return $obj reblessed with the mixin generated, otherwise this will return the mixin itself. If $needs-mixin-attribute is True, this will throw an exception if

Examples, run three ways #

Every example below comes from the official documentation, together with the output that documentation asserts. Each was then executed by Rakudo and by Raku++ when this page was built. Where the three agree, one result is shown; where they do not, all three are — because which of them is wrong is exactly the information worth having.

1 no-output · 1 ok · 2 rakupp-differs

role Metamodel::Mixins {}

Not executed: the documentation states no expected output for this example.

class Billboard {
has Str:D $.advertisement is required;

method vandalism(::?CLASS:D: --> Str:D) { ... }

multi method Str(::?CLASS:D: --> Str:D) { $!advertisement }

role Vandalized[Str:D :$vandalism] {
    method vandalism(::?CLASS:D: --> Str:D) { $vandalism }

    multi method Str(::?CLASS:D: --> Str:D) { $vandalism }
}
}

my Str:D $advertisement = Q:to/ADVERTISEMENT/.chomp;
Brilliant Solutions: sane and knowledgeable consultants.
We have been providing excellent services since 1972!
ADVERTISEMENT
my Str:D $vandalism = Q:to/VANDALISM/.chomp;
      S       s  s ne     k          l   o   l     .
We    e  ee            e  e  e    e    e      e     !
VANDALISM

my Billboard:D $billboard .= new: :$advertisement;
say $billboard eq $advertisement; # OUTPUT: «True␤»

my Billboard:D $draft = $billboard but Billboard::Vandalized[:$vandalism];
say $draft eq $vandalism; # OUTPUT: «True␤»

$billboard does Billboard::Vandalized[:$vandalism];
say $billboard eq $vandalism; # OUTPUT: «True␤»
Documentation
True
True
True
Rakudo
True
True
True
Raku++
False
False
False

Raku++ disagrees with both the documentation and Rakudo — a defect.

class Billboard {
has Str:D $.advertisement is required;

method vandalism(::?CLASS:D: --> Str:D) { ... }

multi method Str(::?CLASS:D: --> Str:D) { $!advertisement }

role Vandalized {
    has Str:D $.vandalism is required is rw;

    multi method Str(::?CLASS:D: --> Str:D) { $!vandalism }
}
}

my Str:D $advertisement = Q:to/ADVERTISEMENT/.chomp;
Brilliant Solutions: sane and knowledgeable consultants.
We have been providing excellent services since 1972!
ADVERTISEMENT
my Str:D $vandalism = Q:to/VANDALISM/.chomp;
      S       s  s ne     k          l   o   l     .
We    e  ee            e  e  e    e    e      e     !
VANDALISM
my Str:D $false-alarm = Qs:to/FALSE-ALARM/.chomp;
$vandalism
⬆️ This is just one of our namesakes we at Brilliant Solutions have been
helping people like you create since 1972!
FALSE-ALARM

my Billboard:D $billboard .= new: :$advertisement;
say $billboard eq $advertisement; # OUTPUT: «True␤»

$billboard does Billboard::Vandalized :value($vandalism);
say $billboard eq $vandalism; # OUTPUT: «True␤»

$billboard.vandalism = $false-alarm;
say $billboard eq $false-alarm; # OUTPUT: «True␤»
Documentation
True
True
True
Rakudo
True
True
True
Raku++
False

Raku++ disagrees with both the documentation and Rakudo — a defect.

class Foo { }
role Bar { }

say Foo.new but Bar;     # OUTPUT: «Foo+{Bar}.new␤»
say Foo.new.^mixin(Bar); # OUTPUT: «Foo+{Bar}.new␤»
Output
Foo+{Bar}.new
Foo+{Bar}.new

Documentation, Rakudo and Raku++ all agree.