In the previous posts, we saw many examples of calling NQP functions from the Perl 6 modules. One of the frequent calls was nqp::getattr. Let us see what that function does.
Here are a couple of recent examples:
nqp::isge_i($pos,0)
&& nqp::isconcrete(nqp::getattr(self,List,'$!reified'))
. . .
nqp::if(
nqp::iseq_i(
nqp::getattr(
nqp::getattr($self,Code,'$!signature'),
Signature,
'$!count'
),1)
When you first look at this, you may think that a string with a dollar such as $!signature or $!count or $!reified is a fancy representation of some internal attribute, and the non-alphabetical characters are used to prevent name clashes.
In fact, this is nothing more than an attribute of the class. A random example from src/core/Any-iterable-methods.pm:
my class IterateMoreWithPhasers does SlippyIterator {
has &!block;
has $!source;
has $!count;
has $!label;
has $!value-buffer;
has $!did-init;
has $!did-iterate;
has $!NEXT;
has $!CAN_FIRE_PHASERS;
The parameters of the nqp::getattr method are: an object, its class, and the name of the attribute.
Try it out in a simple class:
use nqp;
class C {
has $!attr;
method set_attr($value) {
$!attr = $value;
}
}
my $o := nqp::create(C);
$o.set_attr('my value');
nqp::say(nqp::getattr($o, C, '$!attr')); # my value
The class A has one private attribute $!attr, which is set with a manual setter method set_attr.
After the new object is created, the attribute is set to some text value. Then, we use nqp::getattr to read the value from the attribute. Notice that the name of the attributed is passed as a string including the dollar and the exclamation mark characters.
The setter method in this example was needed because you cannot access a private attribute from outside. This is not the case for public attributes, which, in fact, are private attributes, for which Perl 6 creates getter and setter automatically. Here is an updated version of the same program, that employs a public attribute and still uses nqp::getattr:
use nqp;
class C {
has $.attr is rw;
}
my $o := nqp::create(C);
$o.attr = 'other value';
nqp::say(nqp::getattr($o, C, '$!attr')); # other value
This code is simpler and does not require an explicit setter method anymore.
Although the $.attr field is declared with the dot twigil, the actual attribute still resides in an attribute with the name $!attr. The following code does not work:
nqp::say(nqp::getattr($o, C, '$.attr'));
An exception is thrown in this case:
P6opaque: no such attribute '$.attr' in type C when trying to get a value  in block <unit> at getattr-2.pl line 9
That’s all for today. Today, you were using a tiny bit of NQP in your Perl 6 program!
One thought on “🔬20. What does nqp::getattr do in Perl 6?”