Home > Raku > Sneaky Arguments

Sneaky Arguments

While playing with .WHY I stepped onto an ENODOC. Method refers to Signature. Both fail to mention the default signature of a method. The documentation of automatic signatures fails to mention that %_ is always added to methods. Asking greppable6 for mentioning of it revealed plenty of redundant uses of *%_ in methods.

my method m1(:$named) {}
my method m2(:$named, *%_) {}

say &m1.signature;
say &m2.signature;
# OUTPUT: (Mu: :$named, *%_)
          (Mu: :$named, *%_)

The reason why I spotted this is .WHY. In Raku we can add comments that are attached to the language objects that follow them.

class Commented {
    #| this is an attribute
    has $.a-documented-attribute;
    #| this is a method
    method works {
        say ‚working as intended‘;
    }
}
say $c.^can('works')[0].WHY;
say $c.^attributes[0].WHY;
# OUTPUT: this is a method
          this is an attribute

The docs fail to state how to access WHY-nodes for attributes and methods at runtime. We have to go through the MOP here because methods and attributes can be added to a type object at runtime. At least for methods I found a nicer way to handle this.

method works {
    return &?ROUTINE.WHY if %_;
    say ‚working as intended‘;
}
put $c.works(:why);

Oddly, this leads to the awkward situation that I add an undocumented argument to a method that returns the documentation for that method. To be explicit we got the trait is implementation-detail. Being forced to use a multi makes things more cumbersome though.

#| No comment! We are sneaky!
multi method sneaky { say ‚working as intended‘ }
multi method sneaky('why') is implementation-detail {
    return self.^lookup('sneaky').candidates[0].WHY;
}
say $c.sneaky('why');

That leaves the question why I need .WHY on attributes. I do agree with the assessment that JSON is lacking in general. My biggest objection is the lack of comments. For config files being able to tell a co-worker to keep his dirty fingers of a certain line can save lives. Debian is making good use of comments in such files too. It can save a lot of time if you don’t have to read a man page just to change one value. With inline comments on attributes I could express both the structure of data stored in a config file and instructions how to use the config file without another HEREDOC that can get out if sync with the actual code. I really like the structure of NestedText and am playing with adding type information. In NestedText leafs default to Str so that can be omitted. In Raku we get string representations for types for free, we can just add them as text.

I can define the structure of my config file as follows.

use Data::TypedNestedText;

class Phone {
has $.mobile;
has $.home;
has $.office;
}

class Contact {
has $.name;
#| this can be multiline
has $.address;
has $.phone;
has @.additional-roles;
}

For the output I wrote a naive deparser that can produce a NestedText with type annotations.

president[Contact]:
# this can be multiline
address:
> 138 Almond Street
> Topika, Kansas 20697
name: Katheryn McDaniel
phone[Phone]:
home: 1-210-555-8470
mobile: 1-210-555-5297
treasurer[Contact]:
# this can be multiline
address:
> 3636 Buffalo Ave
> Topika, Kansas 20692
name: Fumiko Purvis
phone[Phone]:
office: 1-268-555-0280
additional-roles:
- hug task force
- Christmas party team

This is much easier to read and edit then JSON. Writing the parse might not. I will report back shortly if it turns out to be easier then expected.

Categories: Raku
  1. No comments yet.
  1. October 12, 2020 at 21:10

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

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

Facebook photo

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

Connecting to %s

%d bloggers like this: