Object::InsideOut::Metadata(3pm) | User Contributed Perl Documentation | Object::InsideOut::Metadata(3pm) |
Object::InsideOut::Metadata - Introspection for Object::InsideOut classes
This document describes Object::InsideOut::Metadata version 4.05
package My::Class; { use Object::InsideOut; use Object::InsideOut::Metadata; my @data :Field :Arg('data') :Get('data') :Set('put_data'); my @misc :Field; my %init_args :InitArgs = ( 'INFO' => '', ); sub _init :Init { my ($self, $args) = @_; if (exists($args->{'INFO'})) { $misc[$$self] = 'INFO: ' . $args->{'INFO'}; } } sub misc :lvalue :Method { my $self = shift; $misc[$$self]; } add_meta(__PACKAGE__, 'misc', { 'lvalue' => 1 }); } package main; # Obtain a metadata object for a class my $meta = My::Class->meta(); # ... or obtain a metadata object for an object my $obj = My::Class->new(); my $meta = $obj->meta(); # Obtain the class hierarchy from the metadata object my @classes = $meta->get_classes(); # Obtain information on the parameters for a class's construction my %args = $meta->get_args(); # Obtain information on a class's methods my %methods = $meta->get_methods();
Object::InsideOut provides an introspection API that allows you to obtain metadata on a class's hierarchy, constructor parameters, and methods. This is done through the use of metadata objects that are generated by this class.
In addition, developers can specify metadata data for methods they write for their classes.
To obtain metadata on an Object::InsideOut class or object, you must first generate a metadata object for that class or object. Using that metadata object, one can then obtain information on the class hierarchy, constructor parameters, and methods.
Any Object::InsideOut class potentially has four categories of classes associated with it:
A class's hierarchy consists of any classes in the latter three categories.
my @classes = $obj->meta()->get_classes();
When called in a scalar context, it returns an array ref containing the classes.
Constructor parameters are the arguments given to a class's "->new()" call.
{ 'My::Class' => { 'data' => { 'field' => 1, 'type' => 'numeric', }, 'misc' => { 'mandatory' => 1, }, }, 'My::Parent' => { 'info' => { 'default' => '<none>', }, }, }
The keys for this hash are the Object::IsideOut classes in the class hierarchy. These class keys are paired with hash refs, the keys of which are the names of the parameters for that class (e.g., 'data' and 'misc' for My::Class, and 'info' for My::Parent). The hashes paired to the parameters contain information about the parameter:
When specified, the contents of the resulting array ref must be of the specified subtype:
The methods returned by a metadata object are those that are currently available at the time of the "->get_methods()" call.
The presence of ":Automethod" subroutines in an Object::InsideOut class, or "AUTOLOAD" in a foreign class means that the methods supported by the class may not be determinable. The presence of "AUTOLOAD" in the list of methods for a class should alert the programmer to the fact that more methods may be supported than are listed.
Methods that are excluded are private and hidden methods (see "PERMISSIONS" in Object::InsideOut), methods that begin with an underscore (which, by convention, means they are private), and subroutines named "CLONE", "CLONE_SKIP", and "DESTROY" (which are not methods). While technically a method, "import" is also excluded as it is generally not invoked directly (i.e., it's usually called as part of "use").
{ # Methods exported by Object::InsideOut 'new' => { 'class' => 'My::Class', 'kind' => 'constructor' }, 'clone' => { 'class' => 'My::Class', 'kind' => 'object' }, 'meta' => { 'class' => 'My::Class' }, 'set' => { 'class' => 'My::Class', 'kind' => 'object', 'restricted' => 1 }, # Methods provided by Object::InsideOut 'dump' => { 'class' => 'Object::InsideOut', 'kind' => 'object' }, 'pump' => { 'class' => 'Object::InsideOut', 'kind' => 'class' }, 'inherit' => { 'class' => 'Object::InsideOut', 'kind' => 'object', 'restricted' => 1 }, 'heritage' => { 'class' => 'Object::InsideOut', 'kind' => 'object', 'restricted' => 1 }, 'disinherit' => { 'class' => 'Object::InsideOut', 'kind' => 'object', 'restricted' => 1 }, # Methods generated by Object::InsideOut for My::Class 'set_data' => { 'class' => 'My::Class', 'kind' => 'set', 'type' => 'ARRAY', 'return' => 'new' }, 'get_data' => { 'class' => 'My::Class', 'kind' => 'get' } # Class method provided by My::Class 'my_method' => { 'class' => 'My::Class', 'kind' => 'class' } }
Here are the method metadata that are provided:
Methods that are overridden in child classes are represented as being associated with the most junior class for which they appear.
my %meths = $obj->meta()->get_methods(); my @methods = keys(%meths);
When called in a scalar context, it returns an array ref containing the method names.
Class authors may add the ":Method" attribute to subroutines in their classes to specifically designate them as OO-callable methods. If a method is only a class method or only an object method, this may be added as a parameter to the attribute:
sub my_method :Method(class) { ...
The class or object parameter will appear in the metadata for the method when listed using "->get_methods()".
CAUTION: Be sure not to use ":method" (all lowercase) except as appropriate (see "ARGUMENT VALIDATION" in Object::InsideOut) as this is a Perl reserved attribute.
The ":Sub" attribute can be used to designate subroutines that are not OO-callable methods. These subroutines will not show up as part of the methods listed by "->get_methods()", etc..
Subroutine names beginning with an underscore are, by convention, considered private, and will not show up as part of the methods listed by "->get_methods()", etc..
Class authors may add additional metadata to their methods using the "add_meta()" subroutine which is exported by this package. For example, if the class implements it own ":lvalue" method, it should add that metadata so that it is picked up the "->get_methods()":
package My::Class; { use Object::InsideOut; use Object::InsideOut::Metadata; sub my_method :lvalue :Method(object) { .... } add_meta(__PACKAGE__, 'my_method', 'lvalue', 1); }
The arguments to "add_meta()" are:
When adding multiple metadata for a method, they may be enclosed in a single hash ref:
add_meta(__PACKAGE__, 'my_method', { 'lvalue' => 1, 'return' => 'old' });
If adding metadata for multiple methods, another level of hash may be used:
add_meta(__PACKAGE__, { 'my_method' => { 'lvalue' => 1, 'return' => 'old' }, 'get_info' => { 'my_meta' => 'true' } });
Provide filtering capabilities on the method information returned by "->get_methods()".
Perl 5.8.0 or later
Object::InsideOut
Perl 6 introspection: <http://dev.perl.org/perl6/doc/design/apo/A12.html#Introspection>, and <http://dev.perl.org/perl6/rfc/335.html>
Jerry D. Hedden, <jdhedden AT cpan DOT org>
Copyright 2006 - 2012 Jerry D. Hedden. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
2022-11-29 | perl v5.36.0 |