Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly augment Any?

Tags:

raku

The following program:

use v6.c;

use MONKEY-TYPING;

augment class Any {
    method show0 { self.say }}

augment class List {
    method show1 { self.say }}

<hello world>.show0;
<hello world>.show1;

produces the expected output of:

(hello world)
(hello world)

While this one:

use v6.c;

use MONKEY-TYPING;

augment class Any {
    method show0 { self.say }}

<hello world>.show0;

produces an error:

No such method 'show0' for invocant of type 'List'. Did you mean 'show0'?
  in block <unit> at showcase.p6 line 9

Is that a bug or am I just holding it wrong?

like image 200
matthias krull Avatar asked Oct 09 '18 10:10

matthias krull


People also ask

What types of augmentation are possible?

It identifies two types of augmentation: augmented execution and/or augmented evaluation applied to Augmented Reality (where the target of the task belongs to the physical world) and Augmented Virtuality (where the target of the task belongs to the digital world). ...

How is data augmentation done?

Data augmentation is a process of artificially increasing the amount of data by generating new data points from existing data. This includes adding minor alterations to data or using machine learning models to generate new data points in the latent space of original data to amplify the dataset.


2 Answers

First of all: augmenting core classes, at least in the foreseeable future of Rakudo Perl 6, is not a good idea. It doesn't play well with precompilation.

Secondly: when a class is a subclass of another class, the subclass "knows" from which it inherits. Alas, this doesn't work the other way around: a class does not know of its subclasses (at least at the moment of this writing).

This means that if you augment Any, none of its subclasses know that should also re-compose themselves. In your first example, you do that with the List class by augmenting that. However, if you would reverse the order of the augments, it wouldn't work either, because the List class would get re-composed before the Any class would get re-composed.

It's therefore that it's recommended to mix any extra methods using roles, either into a class, or into an object (mixins of roles)

like image 197
Elizabeth Mattijsen Avatar answered Sep 28 '22 19:09

Elizabeth Mattijsen


A summary of the various comments here and on the issue I created on Github:

As Liz mentioned currently the children types do not see augmentations of their parents. This is true unless there was a flush of the method cache for that type.

This behaviour is a known limitation that will be fixed some time in the future with low priority.

Reconstructing the class with .^compose can be used to make augmented methods known to the children:

use v6.c;

use MONKEY-TYPING;

augment class Any {
    method show0 { self.say }}

List.^compose;

<hello world>.show0; # OUTPUT: (hello world)

Alternatively the qualified class can be accessed directly:

use v6.c;

use MONKEY-TYPING;

augment class Any {
    method show0 { self.say }}

<hello world>.Any::show0; # OUTPUT: (hello world)
like image 41
matthias krull Avatar answered Sep 28 '22 21:09

matthias krull