but
ErrorsCollection

but

Synthesised documentation from language/operators

From language/operators

See Original text in context

multi sub infix:<but>(Mu $obj1Mu   $roleis assoc<non>
multi sub infix:<but>(Mu $obj1Mu:D $obj2is assoc<non>

Creates a copy of $obj with $role mixed in. Since $obj is not modified, but can be used to create immutable values with mixins.

If $role supplies exactly one attribute, an initializer can be passed in parentheses:

role Answerable {
    has $.answer;
}
my $ultimate-question = 'Life, the Universe and Everything' but Answerable(42);
say $ultimate-question;         # OUTPUT: «Life, the Universe and Everything␤» 
say $ultimate-question.^name;   # OUTPUT: «Str+{Answerable}␤» 
say $ultimate-question.answer;  # OUTPUT: «42␤» 

Instead of a role, you can provide an instantiated object. In this case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name and that returns $obj:

my $forty-two = 42 but 'forty two';
say $forty-two+33;    # OUTPUT: «75␤» 
say $forty-two.^name# OUTPUT: «Int+{<anon|1>}␤» 
say $forty-two.Str;   # OUTPUT: «forty two␤» 

Calling ^name shows that the variable is an Int with an anonymous object mixed in. However, that object is of type Str, so the variable, through the mixin, is endowed with a method with that name, which is what we use in the last sentence.

We can also mixin classes, even created on the fly.

my $s = 12 but class Warbles { method hi { 'hello' } }.new;
say $s.Warbles.hi;    # OUTPUT: «hello␤» 
say $s + 42;          # OUTPUT: «54␤» 

To access the mixed-in class, as above, we use the class name as is shown in the second sentence. If methods of the same name are present already, the last mixed in role takes precedence. A list of methods can be provided in parentheses separated by comma. In this case conflicts will be reported at runtime.