Самоанализ: как мы можем получить имя класса внутри класса? - PullRequest
8 голосов
/ 12 мая 2019

Скажем, у нас есть

class Foo {}

Есть ли способ получить "Foo" из класса?

Ответы [ 2 ]

9 голосов
/ 12 мая 2019

Да.

class Foo {
    say ::?CLASS.^name; # OUTPUT: Foo
}
7 голосов
/ 12 мая 2019

Решение Kaiepi имеет свое место, о котором я расскажу ниже, но также рассмотрим:

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

Foo.perl

Это дает простой ответ на ваш буквальный вопрос (хотя он игнорирует то, что вы действительно ищете, как объяснено в вашем комментарии ниже и как подсказано тегом metaprogramming и вашим использованием слова "самоанализ").

OUR.WHO

Я думаю, что это обычно более уместно, чем ::?CLASS.^name по нескольким причинам:

  • выглядит менее шумно.

  • Работает для всех форм пакетов, т. Е. Объявленных с помощью встроенных объявлений package, module, grammar или role, а также class, а также пользовательские объявления, такие как actor, monitor и т. д.

  • Приведет читателей к наиболее актуальным вопросам, если они исследуют OUR и / или .WHO в отличие от в основном отвлекающих тайн, если они исследуют ::?... конструкция .

::?CLASS против ::?PACKAGE

OUR.WHO работает только в грамматическом слоте value , а не в грамматическом слоте type . Для последнего вам нужна подходящая форма ::?..., например:

class Foo { has ::?CLASS $bar }

И эти ::?... формы также работают как значения:

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

Так что, несмотря на их относительное безобразие, в этом конкретном смысле они более общие. Тем не менее, если общность выше, то ::?PACKAGE становится лучше, поскольку она работает для всех форм упаковки.

...