Archive for January, 2019

A picky caller

January 23, 2019 1 comment

I have got myself a paradoxical harddrive by combining a fast ssd and a sizeable disk by setting up a a bcache on my linux box. Now I got a harddrive that is really fast with small files. There are a few stats bcache is providing via sysfs. To watch them one requires to read a few text files. A well suited task for slurp. I ended up with a bunch of pointy blocks that look like this:

-> $cache {
slurp("/sys/fs/bcache/$cache/cache_available_percent").chomp ~ '%'

I put them together with a name into an Array to be able to loop over them. As it turned out there are two groups of pointies. The one group needs the name of the bcache-block device which holds the actualy filesystem. The other group gets the UUID of the cache group. I need to group the output of the two groups so I get:

dirty data: 36.0k
hit ratio: 62% 66% 50% 0%
bypassed: 7.0G 2.4G 65.1M 9.1M
cache available: 94%

I could have split up the array but figured that I can check the signature of the pointy instead to select what is being output.

for bcache-devs() -> $dev {
  with $dev {
  say BOLD $dev, ':';
  for @stats -> $name, &f {
  next unless &f.signature.params».name eq '$dev';
  put "\t", $name, ': ', .&f

If the name of the positional doesn’t fit I just skip the output.

Next I tried to match the signature by adding subsets of Str to the signature of the pointes. Sadly matching a signature literal like so doesn’t work in this case.

subset Dev of Str;
say 'match' if &f.signature ~~ :(Dev $dev);

If I would define my one classes that would certainly work. It seems the sloppy matching of subsets is working as intended. A bit of a shame because subsets are so easy to set up. For my example just matching the parameter name is fine because it saves time when typing the pointies.

Nonetheless it’s really neat that the caller can has a say if it likes the signature of the callee in Perl 6.

Categories: Perl6

Iterating past the finish

January 11, 2019 Leave a comment

A while ago the question was raised how to augment Any. As it turns out the augmenting part is working but the newly added method is not propagated to children of buildin types. One can force the propagation by calling .compose on all type objects. Getting a list of all parents is done with .^mro and the check is done with .

augment class Cool { method HTML { } }
if Cool ∈ T.HOW.mro(T) { T.HOW.compose(T); }

I stepped on a Dragon

The tricky part is to get all predefined classes. Mostly because there is a lot of stuff in CORE:: that doesn’t even implement the interfaces to call methods. We can call .DEFINITE because that’s not a method. So we can weed out all predefined objects and are left with type objects and stuff that’s leaking from NQP into Perl 6-land. Those beasties don’t implement .mro so by guarding with try we can bild a list of all Perl 6 type objects. Those type objects contain IterationEnd. Hence we can’t trust for or anything else that is using iterators to loop over a list. There is also Slip in the list. We can help that by using binding everywhere.

my @a = CORE::.values;
my @types;
for 0..^@a.elems -> $i {
my \T := @a[$i];
try @types[$++] := T if not T.DEFINITE;

for 0..^@types.elems -> $i {
my \T := @types[$i];
try if Cool ∈ T.HOW.mro(T) {

And there we have it. All children of Cool have been re-.composed.

It’s no magic!

There are a few things I learned. Firstly much of the magic behind Perl 6 are just type checks. Anything that deals with iteration of lists or similar constructs is checking for Slip or IterationEnd and branching out to deal with their special nature.

And secondly there are a lot of interfaces leaking into spec-land that have no business there. I’m worried that might bite us later because any useful interface will be abused by programmers sooner or later. I would prefer the inner workings of Rakudo to be well hidden.

I found a way to deal with agumenting build in types so it can’t be long before the core devs fix that bug.

Categories: Perl6