brian d foy
brian d foy

Reputation: 132822

Why does Perl 6's string concatenation not like .WHAT?

I'm puzzled about this bit of code where I apparently can't call the WHAT method in a string concatenation?

my $object = 'Camelia';

say $object;
say $object.WHAT;
say "^name: The object is a " ~ $object.^name;
say "WHAT: The object is a " ~ $object.WHAT;

The output shows that calling ^name works (a metamethod from Metamodel::ClassHOW), but Perl 6 is confused by .WHAT as if there's a precedence issue.

Camelia
(Str)
^name: The object is a Str
Use of uninitialized value of type Str in string context
Any of .^name, .perl, .gist, or .say can stringify undefined things, if needed.  in block <unit> at meta_methods.p6 line 7
WHAT: The object is a

My Perl 6:

This is Rakudo version 2015.12-219-gd67cb03 built on MoarVM version 2015.12-29-g8079ca5
implementing Perl 6.c.

Upvotes: 9

Views: 432

Answers (2)

CIAvash
CIAvash

Reputation: 716

A quote from Perl 6's IRC channel, user FROGGS:

.WHAT gives you back a type, which is meant to warn if you interpolate or concat it or do math with it

In your example, $object is a Str, so $object.WHAT gives you the Str type.

In other words it's like writing:

say "WHAT: The object is a " ~ Str;

Edit: It seems your real question is "Why does Perl 6's string concatenation not like types?"

As others have mentioned, types are undefined and concatenation works on defined values. As Perl 6's warning message says, you need to use any of .^name, .perl, .gist to stringify undefined things.

These two will work because say uses .gist to stringify:

say Str;

say "The object is ", Str;

Upvotes: 7

raiph
raiph

Reputation: 32414

.WHAT returns a type object, an undefined object

Like most routines/operators, concatenation assumes its arguments are defined. But the .WHAT in your last line returns a type object and a type object is not defined. So the result is a warning and stringification to the empty string.


If you want to concatenate an undefined object without generating a warning and instead stringify it into the object's type name you must explicitly .^name, .gist or .perl it eg:

say "The object is a " ~ $object.^name
say "The object is a " ~ $object.WHAT.gist

displays:

The object is a Str
The object is a (Str)

Upvotes: 7

Related Questions