🔬20. What does nqp::getattr do in Perl 6?

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?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s