Интроспекция

Интроспеция [4] процесс сбора информации об объектах в программе во время ее выполнения.

Возьмем объект $o класса Programmer и, основываясь на содержимом классов из предыдущей секции, зададим несколько вопросов:

    if $o ~~ Employee { say "It's an employee" };
    if $o ~~ GeekCook { say "It's a geeky cook" };
    say $o.WHAT;
    say $o.perl;
    say $o.^methods(:local).join(', ');

Результат будет выглядеть следующим образом:

    It's an employee
    Programmer()
    Programmer.new(known_languages => ["Perl", "Python", "Pascal"], favorite_editor => "gvim", salary => "too small")
    code_to_solve, known_languages, favorite_editor

Первые два теста представляют собой умное сопоставление (smart-match) объекта с именами классов. Если объект того же класса или наследуется от указанного, результатом является истина. Таким образом образом $o является объектом класса Employee или унаследованным от него, но не GeekCook.

Метод .WHAT возвращает объект-тип, ассоциированный с объектом $o, который сообщает точный класс. В данном примере - Programmer.

$o.perl возвращает исполняемую строку кода Perl, которая воссоздает оригинальный объект $o. Данный код в основном не является работающим [5], но очень полезен для отладки простых объектов.

Наконец, $o.^methods(:local) выводит список доступных для вызовов методов объекта $o. Именованный параметр :local ограничивает этот список методами определенными в классе Employee и исключает унаследованные.

Синтаксис вызова метода с .^ вместо одиночной точки подразумевает, что метод на самом деле вызывается у мета класса, управляющего свойствами класса Employee или любого другого. Этот мета класс предоставляет дополнительные способы интроспекции:

    say $o.^attributes.join(', ');
    say $o.^parents.join(', ');  

Интроспекция полезна при отладке, а также при изучении языка или новых библиотек. В случаях когда требуется установить тип возвращаемого функцией объекта используется .WHAT, а также код воссоздания, возвращаемый .perl. В дополнение результат ^.methods расскажет, что вы можете делать с объектом.

Но есть другие применения интроспекции. Например, процедурам сериализации объектов необходима знать об атрибутах объекта.



[4] Интроспекция (англ. type /introspection/) в программировании - возможность в некоторых объектно-ориентированных языках определить тип и структуру объекта во время выполнения программы. Эта возможность особенно заметна в языке Objective C, однако имеется во всех языках, позволяющих манипулировать типами объектов как объектами первого класса. Интроспекция может использоваться для реализации полиморфизма. В Java эта возможность называется рефлекцией

[5] например замыкания таким образом не могут быть воспроизведены. Если вы не знаете что такое замыкания не волнуйтесь. В существующей на сегодня реализации есть проблемы с отображением цикличных структур, но в ближайшем они будут решены.