Attribute Reference
Member variable
What it is #
class Boo {
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 new #
Creates a new attribute. The following named arguments are required: - $name contains the attribute's name, which should always be a
method name #
method name(Attribute:D: --> Str:D)
Returns Str:D.
Returns the name of the attribute. Note that this is always the private name, so if an attribute is declared as has $.a, the name returned is $!a.
method package #
method package()
Returns the package (class/grammar/role) to which this attribute belongs.
method has_accessor #
method has_accessor(Attribute:D: --> Bool:D)
Returns Bool:D.
Returns True if the attribute has a public accessor method.
method rw #
method rw(Attribute:D: --> Bool:D)
Returns Bool:D.
Returns True for attributes that have the "is rw" trait applied to them.
method readonly #
method readonly(Attribute:D: --> Bool:D)
Returns Bool:D.
Returns True for readonly attributes, which is the default, or False for attributes marked as is rw.
method required #
method required(Attribute:D: --> Any:D)
Returns Any:D.
Returns 1 for attributes that have the "is required" trait applied, or Mu if the attribute did not have that trait applied. If the "is required" trait is applied with a string, then that string will be returned instead of 1.
method type #
method type(Attribute:D: --> Mu)
Returns Mu.
Returns the type constraint of the attribute.
method get_value #
method get_value(Mu $obj)
Returns the value stored in this attribute of object $obj. Note that this method violates encapsulation of the object, and should be used with care.
method set_value #
method set_value(Mu $obj, Mu \new_val)
Binds the value new_val to this attribute of object $obj. Note that this method violates encapsulation of the object, and should be used with care. Here be dragons.
method gist #
multi method gist(Attribute:D:)
Returns the name of the type followed by the name of the attribute. Since say implicitly calls .gist, that is what produces the output here.
method is_built #
method is_built()
Returns True if the attribute had the is built trait applied to it, otherwise returns False.
method is_bound #
method is_bound()
Returns True if the attribute had the is built trait applied to it with :bind as an argument, otherwise returns False.
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.
2 all-differ · 19 no-output · 2 not-runnable · 8 ok · 3 rakupp-differs
class Attribute { }Not executed: the documentation states no expected output for this example.
class WithAttributes {
has $.attribute;
has $.attribute-two-electric-boogaloo;
has $.yet-another-attribute;
}
.say for WithAttributes.^attributes(:local).map(*.name);
# OUTPUT:
# $!attribute
# $!attribute-two-electric-boogaloo
# $!yet-another-attributeNot executed: the documentation states no expected output for this example.
class WithAttribute {
has $.attribute;
}Not executed: the documentation states no expected output for this example.
BEGIN {
constant WithAttribute = Metamodel::ClassHOW.new_type: :name<WithAttribute>;
WithAttribute.^add_attribute: Attribute.new:
:name<$!attribute>, :type(Any), :package(WithAttribute),
:1has_accessor;
WithAttribute.^compose;
}Not executed: the documentation states no expected output for this example.
class C {
has $.a is default(42) is rw = 666
}
my $c = C.new;
say $c;
$c.a = Nil;
say $c;
# OUTPUT: «C.new(a => 666)C.new(a => 42)»
class Foo {
has @.bar is default(42) is rw
};
my $foo = Foo.new( bar => <a b c> );
$foo.bar =Nil;
say $foo; # OUTPUT: «Foo.new(bar => [42])»C.new(a => 666)
C.new(a => 42)
Foo.new(bar => [42])
C.new(a => 666)
C.new(a => 42)
Foo.new(bar => [42])
C.new(a => 666)
C.new(a => Nil)
Foo.new(bar => Nil)
Raku++ disagrees with both the documentation and Rakudo — a defect.
multi trait_mod:<is> (Attribute $attr, :$required!)
Not executed: the documentation states no expected output for this example.
class C {
has $.a is required
}
my $c = C.new;
CATCH{ default { say .^name, ': ', .Str } }
# OUTPUT: «X::Attribute::Required: The attribute '$!a' is required, but you did not provide a value for it.»X::Attribute::Required: The attribute '$!a' is required, but you did not provide a value for it.
Documentation, Rakudo and Raku++ all agree.
class Power {
has Numeric:D $.base is required;
has Numeric:D $.exponent is required;
multi method Numeric(::?CLASS:D: --> Numeric:D) {
$!base ** $!exponent
}
}Not executed: the documentation states no expected output for this example.
class D {
has $.a is required("it is a good idea");
}
my $d = D.new;
CATCH{ default { say .^name, ': ', .Str } }
# OUTPUT: «X::Attribute::Required: The attribute '$!a' is required because it is a good idea,but you did not provide a value for it.»X::Attribute::Required: The attribute '$!a' is required because it is a good idea,
but you did not provide a value for it.
Documentation, Rakudo and Raku++ all agree.
multi trait_mod:<is>(Attribute:D $r, :$DEPRECATED!)
Not executed: the documentation states no expected output for this example.
class C {
has $.foo is DEPRECATED("'bar'");
}
my $c = C.new( foo => 42 ); # doesn't trigger with initialization (yet)
say $c.foo; # does trigger on usageNot executed: the documentation states no expected output for this example.
# Saw 1 occurrence of deprecated code. # ===================================== # Method foo (from C) seen at: # script.raku, line 5 # Please use 'bar' instead.
Not executed: the documentation states no expected output for this example.
multi trait_mod:<is> (Attribute:D $attr, :$rw!)
Not executed: the documentation states no expected output for this example.
has $.bar is rw; has $.baz;
Not executed: the documentation states no expected output for this example.
multi trait_mod:<is> (Attribute:D $attr, :readonly($)!)
Not executed: the documentation states no expected output for this example.
=begin code :skip-test<illustrates error>
class Thing is rw {
has $.form;
has $.matter is readonly;
};Not executed: the documentation states no expected output for this example.
my $t = Thing.new(matter => "copper", form => "cubic"); $t.form = "round"; # OK, form is rw $t.matter = "iron"; # not OK, matter is readonly # OUTPUT: «Cannot modify an immutable Str (copper)...» =end code
Neither engine can run this in isolation — the example depends on context from the surrounding text.
multi trait_mod:<is>(Attribute:D $a, :$built!)
Not executed: the documentation states no expected output for this example.
class Foo {
has $!bar is built; # same as `is built(True)`
has $.baz is built(False);
has $!qux is built(:bind);Not executed: the documentation states no expected output for this example.
method bar(::?CLASS:D:) { $!bar }
method qux(::?CLASS:D:) { $!qux }
}Not executed: the documentation states no expected output for this example.
my Foo:D $foo .= new: :bar[], :baz[], :qux[]; say $foo.bar.raku; # OUTPUT: «$[]» say $foo.baz.raku; # OUTPUT: «Any» say $foo.qux.raku; # OUTPUT: «[]»
Neither engine can run this in isolation — the example depends on context from the surrounding text.
class Foo {
has $!foo is built(:bind) = Proxy.new: :STORE{...}, :FETCH{...}
}Not executed: the documentation states no expected output for this example.
method new( Attribute:_: :$name!, :$type!, :$package!, :$inlined = 0, :$has_accessor = 0, :$is_built = $has_accessor, :$is_bound = 0, :$positional_delegate = 0, :$associative_delegate = 0, *%other )
Not executed: the documentation states no expected output for this example.
class Foo {
has @!bar;
}
my $a = Foo.^attributes(:local)[0];
say $a.name; # OUTPUT: «@!bar»@!bar
Documentation, Rakudo and Raku++ all agree.
class Boo {
has @!baz;
}
my $a = Boo.^attributes(:local)[0];
say $a.package; # OUTPUT: «(Boo)»(Boo)
(Boo)
(Mu)
Raku++ disagrees with both the documentation and Rakudo — a defect.
class Container {
has $!private;
has $.public;
}
my $private = Container.^attributes(:local)[0];
my $public = Container.^attributes(:local)[1];
say $private.has_accessor; # OUTPUT: «False»
say $public.has_accessor; # OUTPUT: «True»False
True
Documentation, Rakudo and Raku++ all agree.
class Library {
has $.address; # Read-only value
has @.new-books is rw;
}
my $addr = Library.^attributes(:local)[0];
my $new-books = Library.^attributes(:local)[1];
say $addr.rw; # OUTPUT: «False»
say $new-books.rw; # OUTPUT: «True»False
True
Documentation, Rakudo and Raku++ all agree.
class Library {
has $.address; # Read-only value
has @.new-books is rw;
}
my $addr = Library.^attributes(:local)[0];
my $new-books = Library.^attributes(:local)[1];
say $addr.readonly; # OUTPUT: «True»
say $new-books.readonly; # OUTPUT: «False»True
False
Documentation, Rakudo and Raku++ all agree.
class Library {
has $.address is required;
has @.new-books is required("we always need more books");
}
my $addr = Library.^attributes(:local)[0];
my $new-books = Library.^attributes(:local)[1];
say $addr.required; # OUTPUT: «1»
say $new-books.readonly; # OUTPUT: «"we always need more books"»1
"we always need more books"
1
True
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
class TypeHouse {
has Int @.array;
has $!scalar;
has @.mystery;
}
my @types = TypeHouse.^attributes(:local)[0..2];
for 0..2 { say @types[$_].type }
# OUTPUT: «(Positional[Int])
# (Mu)
# (Positional)»Not executed: the documentation states no expected output for this example.
class Violated {
has $!private-thing = 5;
}
my $private = Violated.^attributes(:local)[0];
say $private.get_value(Violated.new); # OUTPUT: «5»5
Documentation, Rakudo and Raku++ all agree.
class A {
has $!a = 5;
method speak() { say $!a; }
}
my $attr = A.^attributes(:local)[0];
my $a = A.new;
$a.speak; # OUTPUT: «5»
$attr.set_value($a, 42);
$a.speak; # OUTPUT: «42»5
42
Documentation, Rakudo and Raku++ all agree.
class Hero {
has @!inventory;
has Str $.name;
submethod BUILD( :$name, :@inventory ) {
$!name = $name;
@!inventory = @inventory
}
}
say Hero.^attributes(:local)[0]; # OUTPUT: «Positional @!inventory»Positional @!inventory
Positional @!inventory
Mu @!inventory
Raku++ disagrees with both the documentation and Rakudo — a defect.
class Hangout {
has $.table;
has $.bar is DEPRECATED("the patio");
}
my $attr-table = Hangout.^attributes(:local)[0];
my $attr-bar = Hangout.^attributes(:local)[1];
with $attr-table.?DEPRECATED -> $text { # does not trigger
say "Table is deprecated with '$text'";
# OUTPUT:
}
with $attr-bar.?DEPRECATED -> $text {
say "Bar is deprecated with '$text'";
# OUTPUT: «Bar is deprecated with 'the patio'"»
}Bar is deprecated with 'the patio'"
Bar is deprecated with 'the patio'
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.