Home > Raku > It felt like a bug

It felt like a bug

IO::Path provides quite a few bits of information about a file. What is missing is it’s true type. File endings can be deceiving. On operation systems that sport file we can get a clear picture. Shelling to get the mimetype with file -b -i is a bit slow so I tried to add a .hyper.map on a list of filenames and mixed in a role to IO::Path. I stepped on something that felt like a bug but wasn’t. Following is the golfed code to illustrade the probem.

my @list = 1..10;
my @results;
@results = @list[^24].hyper(:degree(2), :batch(1)).map({
    my $type = run('/bin/ls', :out).out.slurp.chars;
    $_ but role Mime { has $.mime = $type }
});

Rakudo seems to try to form a closure with the role but frees the data that is stored somewhere. This is only noticible when threading slows things down. It is a rare case where the syntax is valid but the semantics are wrong. So the grammar that is Raku can parse it but the compiler can`t do anything usefull with that match. It somehow speaks highly of the compiler to handle this case without crashing. Yet, a warning would be nice. As jnthn pointed out, this is not the right way to use a role.

Of cause there is a proper way to handle such a case. We need to define a role with a parameter that we can use as a default to our attribute.

sub get-filetype(IO() $_){ run('/usr/bin/file', '-b', '-i', .basename, :out).out.slurp }
role Mime[$type] { has $.mime = $type }
@results = @list[^24].hyper(:degree(2), :batch(1)).map({
    my $type = run('/bin/ls', :out).out.slurp.chars;
    $_ but Mime[$type]
});

I did not manage to use an anonymous parametric role. We can define one, store it in scalar but can’t instantiate it. Using the subscript [] on a scalar (and many other things) will tell the grammar to assume we want to work with a Positional.

my $R = role :: [$t] {};
dd $R;
dd $R[42];
# OUTOUT: <anon|10> $R = <anon|10>
#         Could not instantiate role '<anon|10>':
#         Too few positionals passed; expected 2 arguments but got 1

There is a way to use the MOP to do so. I did find the right method in Metamodel::ParametricRoleHOW but failed to figure out how to use it. (If you do know how to use .^parameterize please provide a code snippet.)

Not really closure forming roles seem to be a case where the grammar can handle it but the compiler doesn’t. Which leaves the question how one is supposed to document a thing that should not exist. It is a trap and we have a section for those. But this is placed pretty far from the description of roles. The first two pull requests are written and more will need to follow.

I’m glad that the docs are written in a language that supports hyperlinks. It would be pretty difficult to describe the network that is Raku in a linear thing like a book.

Categories: Raku
  1. No comments yet.
  1. June 22, 2020 at 16:30

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 )

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

%d bloggers like this: