Object...etadata(3pm)
π Object::InsideOut::Metadata π
okay so this is the manual page for Object::InsideOut::Metadata(3pm) β it's from the User Contributed Perl Documentation section, and bestie, it's literally introspection but make it fashion. π¦
β¨ NAME β¨
Object::InsideOut::Metadata β Introspection for Object::InsideOut classes π
πΈ VERSION πΈ
This document describes Object::InsideOut::Metadata version 4.05. periodt.
π SYNOPSIS π
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();
π DESCRIPTION π
Object::InsideOut gives you an introspection API, which is the fancy way of saying you can peek inside a class and see what it's made of. Specifically you can pull metadata about a class's hierarchy, its constructor parameters, and its methods. All of that happens through metadata objects, and those metadata objects are generated by this class right here. π
Also, plot twist: developers can specify metadata for methods they write for their own classes. So you're not just reading the vibe, you can set the vibe too. β¨
π METADATA OBJECT π
To get metadata on an Object::InsideOut class or object, step one is always: generate a metadata object for that class or object. Once you have it, you can ask it about the class hierarchy, the constructor parameters, and the methods. That's the whole flow, bestie. π«Ά
my $meta = My::Class->meta();
my $meta = $obj->meta();
The ->meta() method is exported by Object::InsideOut into every single class, and it hands you back an Object::InsideOut::Metadata object. You can then query that object for info about the class you invoked it on, or about the class of the object you invoked it on. π
π CLASS HIERARCHY π
Every Object::InsideOut class potentially has four categories of classes associated with it:
Object::InsideOutβ It's the basis for allObject::InsideOutclasses, but ngl, it is not an object class per se, because you can't create objects from it (i.e., you can't doObject::InsideOut->new()). So like,My::Class->isa('Object::InsideOut')will return true, but becauseObject::InsideOutisn't an object class, it's not considered part of a class's hierarchy. π- The class itself β A class's hierarchy always includes itself. main character energy, honestly. π
- Parent classes β These are all the
Object::InsideOutclasses up the inheritance tree that a class is derived from. - Foreign classes β These are non-
Object::InsideOutclasses that a class inherits from. (See "FOREIGN CLASS INHERITANCE" in Object::InsideOut.) Heads up: because of implementation details, foreign classes do not show up in a class's@ISAarray. ButObject::InsideOutimplements its own version of->isa()that handles foreign classes, so it's fine. π§
A class's hierarchy consists of any classes in the latter three categories.
$meta->get_classes();β When called in an array context, returns a list that makes up the class hierarchy for the class or object used to generate the metadata object. When called in a scalar context, it returns an array ref.My::Class->isa();/$obj->isa();β When called in an array context, calling->isa()with no arguments on anObject::InsideOutclass or object returns a list of the classes in the class hierarchy for that class or object. It's equivalent to:
my @classes = $obj->meta()->get_classes();
When called in a scalar context, it returns an array ref containing the classes.
π οΈ CONSTRUCTOR PARAMETERS π οΈ
Constructor parameters are the arguments you hand to a class's ->new() call. Simple as that. π
$meta->get_args();β Returns a hash (or a hash ref in scalar context) containing info on the parameters that can be used to construct an object from the class associated with the metadata object. Here's an example of what that hash looks like:
{
'My::Class' => {
'data' => {
'field' => 1,
'type' => 'numeric',
},
'misc' => {
'mandatory' => 1,
},
},
'My::Parent' => {
'info' => {
'default' => '<none>',
},
},
}
The keys of this hash are the Object::InsideOut classes in the class hierarchy. Each class key is paired with a hash ref, and the keys of that hash are the names of the parameters for that class (so like, 'data' and 'misc' for My::Class, and 'info' for My::Parent). The hashes paired to the parameters contain the info about each parameter:
fieldβ The parameter corresponds directly to a class field, and gets automatically processed during object creation. See "Field-Specific Parameters" in Object::InsideOut.mandatoryβ The parameter is required for object creation. See "Mandatory Parameters" in Object::InsideOut.defaultβ The default value assigned to the parameter if it's not found in the arguments to->new(). See "Default Values" in Object::InsideOut.preprocβ The code ref for the subroutine used to preprocess a parameter's value. See "Parameter Preprocessing" in Object::InsideOut.typeβ The form of type checking performed on the parameter. See "TYPE CHECKING" in Object::InsideOut for more details.'numeric'β Parameter takes a numeric value as recognized byScalar::Util::looks_like_number().'list'/'list(_subtype_)'β Parameter takes a single value (which is then placed in an array ref) or an array ref.- When specified, the contents of the resulting array ref must be of the specified subtype:
'numeric'β Same as for the basic type above.- A class name β Same as for the basic type below.
- A reference type β Any reference type as returned by
ref().
- When specified, the contents of the resulting array ref must be of the specified subtype:
'ARRAY(_subtype_)'β Parameter takes an array ref with contents of the specified subtype as per the above.- A class name β Parameter takes an object of a specified class, or one of its sub-classes as recognized by
->isa(). - Other reference type β Parameter takes a reference of the specified type as returned by
ref(). - A code ref β Parameter takes a value that is type-checked by the code ref paired to the
'type'key.
β¨ METHODS METADATA β¨
okay so bestie, the methods you get back from a metadata object are literally just the ones that exist at the exact moment you call ->get_methods(). No time travel, no future methods, just vibes-at-this-second. π«
If your Object::InsideOut class has :Automethod subroutines, or a foreign class is running AUTOLOAD, then the methods that class supports may just... not be fully knowable. π So if you see AUTOLOAD sitting in the list of methods for a class, that's your lil heads-up: there might be more methods than are listed. Don't be shocked, bestie.
Now, the stuff that gets excluded (the private-only zone, no entry π ):
- private and hidden methods (peep
"PERMISSIONS"in Object::InsideOut for the tea) - any method whose name starts with an underscore (by convention that means it's private, okay?)
- subroutines named
CLONE,CLONE_SKIP, andDESTROYβ these aren't methods at all, they're just doing their own thing - and
importβ technically it is a method, but it's excluded because it's generally not invoked directly (it usually gets called as part ofuse, iykyk)
$meta->get_methods();
Returns a hash (or a hash ref if you're in scalar context) stuffed with info about the methods for the class tied to that metadata object. The keys are the method names, and paired to each name is a hash ref with the metadata about that method. Here's a whole example, enjoy the feast:
{
# 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's the method metadata you get served: π½οΈ
class
The class in whose symbol table the method resides. That method might live in the class's own code, it might be exported by another class, or Object::InsideOut might have generated it. Either way, we're telling you where it's at.
Methods that get overridden in child classes are represented as being associated with the most junior class for which they appear. π
kind
Designation of the characteristic of the method. The lineup:
constructorβ the->new()method, obviously. πget,setoraccessorβ a get, set, or combined accessor generated by Object::InsideOut. See"AcCESSOR GENERATION"in Object::InsideOut.cumulative, orcumulative (bottom up)chained, orchained (bottom up)β a cumulative or chained method. See"CUMULATIVE METHODS"in Object::InsideOut, and"CHAINED METHODS"in Object::InsideOut. The class associated with these methods is the most junior class in which they appear.classβ a method that's callable only on a class (like,My::Class->my_method()).objectβ a method that's callable only on an object (like,$obj->get_data()).foreignβ a subroutine found in a foreign class's symbol table. Bestie, you have to check the class's documentation yourself to figure out which ones are actually methods and what kind they are. We can't do that for you, sorry. π«Άoverloadβ a subroutine used for object coercion. These may be called as methods, but that's not normally how they get used.automethodβ associated with an AUTOLOAD method for an Object::InsideOut class that implements an:Automethodsubroutine. See"AUTOMETHODS"in Object::InsideOut.
type
The type checking that gets done on arguments to set/combined accessors generated by Object::InsideOut. See "TYPE CHECKING" in Object::InsideOut.
return
The value returned by a set/combined accessor generated by Object::InsideOut. See "Set Accessor Return Value" in Object::InsideOut.
lvalue
The method is an :lvalue accessor. iconic, honestly.
restricted
The method is restricted (meaning: callable only from within the class hierarchy, not callable from application code). See "PERMISSIONS" in Object::InsideOut.
My::Class->can();
$obj->can();
When you call ->can() with no arguments on an Object::InsideOut class or object in an array context, you get back a list of the method names for that class or object. It's literally equivalent to:
my %meths = $obj->meta()->get_methods();
my @methods = keys(%meths);
And when you call it in scalar context, it hands you back an array ref holding those method names. same energy, different container. β¨
πΈ METADATA ATTRIBUTES πΈ
Class authors, this one's for you: you can slap the :Method attribute onto subroutines in your classes to specifically designate them as OO-callable methods. And if a method is only a class method or only an object method, you can pass that in as a parameter to the attribute:
sub my_method :Method(class)
{
...
That class or object parameter will show up in the metadata for the method when it's listed using ->get_methods().
β οΈ CAUTION: pls be so careful not to use:method(all lowercase) except where it's appropriate (see"ARGUMENT VALIDATION"in Object::InsideOut) β because that one is a Perl reserved attribute. not the vibe you want.
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.
Also, subroutine names beginning with an underscore are, by convention, considered private, and they will not show up as part of the methods listed by ->get_methods(), etc.
π ADDING METADATA π
Class authors can add extra metadata to their methods using the add_meta() subroutine, which is exported by this package. For example, if your class implements its own :lvalue method, you should add that metadata so it gets picked up by ->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:
- Class name β this can usually be designated using the special literal
__PACKAGE__. - Method name
- Metadata name β this can be any of the metadata names under
"METHODS METADATA", or it can be whatever additional name the programmer chooses to implement. - Metadata value
When you're adding multiple metadata for a method, you can enclose them in a single hash ref:
add_meta(__PACKAGE__, 'my_method', { 'lvalue' => 1,
'return' => 'old' });
And if you're adding metadata for multiple methods, you get another whole level of hash to play with:
add_meta(__PACKAGE__, { 'my_method' => { 'lvalue' => 1,
'return' => 'old' },
'get_info' => { 'my_meta' => 'true' } });
π TO DO
Provide filtering capabilities on the method information returned by ->get_methods(). (one day, bestie. one day.)
β REQUIREMENTS
Perl 5.8.0 or later
π SEE ALSO
- 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>
π AUTHOR
Jerry D. Hedden, <jdhedden AT cpan DOT org>
π COPYRIGHT AND LICENSE
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.
aaaand that's a wrap on the whole page, bestie! π this was rendered by perl v5.36.0 and the page itself is dated 2022-11-29. go forth and introspect, you absolute main character. π
β¨
π¦ where this page comes from
- debian bookworm: libobject-insideout-perl 4.05-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libobject-insideout-perl 4.05-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libobject-insideout-perl 4.05-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libobject-insideout-perl 4.05-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libobject-insideout-perl 4.05-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms