Say we have

class Foo {}

Is there a way to obtain "Foo" from within the class?

2 Answers

9
Kaiepi On Best Solutions

Yes.

class Foo {
    say ::?CLASS.^name; # OUTPUT: Foo
}
7
raiph On

Kaiepi's solution has its place, which I'll get to below, but also consider:

class Foo {
    say Foo.perl;         # Foo
    say OUR.WHO;          # Foo
    ::?PACKAGE
}

Foo.perl

This provides a simple answer to your literal question (though it ignores what you're really after, as explained in your comment below and as suggested by the metaprogramming tag and your use of the word "introspection").

OUR.WHO

I think this is typically more appropriate than ::?CLASS.^name for several reasons:

  • Looks less line-noisy.

  • Works for all forms of package, i.e. ones declared with the built in declarators package, module, grammar, or role as well as class, and also custom declarators like actor, monitor, etc.

  • Will lead readers to mostly directly pertinent issues if they investigate OUR and/or .WHO in contrast to mostly distracting arcana if they investigate the ::?... construct.

::?CLASS vs ::?PACKAGE

OUR.WHO only works in a value grammatical slot, not a type grammatical slot. For the latter you need a suitable ::?... form, eg:

class Foo { has ::?CLASS $bar }

And these ::?... forms also work as values:

class Foo { has $bar = ::?CLASS }

So, despite their relative ugliness, they're more general in this particular sense. That said, if generality is at a premium then ::?PACKAGE goes one better because it works for all forms of package.