Class::...:Engine(3)
Welcome to the Class::...:Engine(3) page β yep, that's the manual name right there, and it's also hanging out in the User Contributed Perl Documentation corner because headers stay extra. π
π NAME π
Class::MethodMaker::Engine β literally the parameter passing, method installation & non-data-structure methods of Class::MethodMaker. Backstage pass energy, bestie. ποΈβ¨
β¨ SYNOPSIS β¨
Okay, real talk: this class is for internal implementation only. It is not a public API. No cap. π
The non-data-structure methods do form part of the public API, but they're not called directly β they get called through the use/import interface, just like the data-structure methods. Same vibe, different lane. π«
πΈ The Class::MethodMaker Method Installation Engine πΈ
π import π
import does the argument parsing so everything's ready for calling create_methods. This is the exact spot where v1 & v2 calls get distinguished β iykyk. π
This is implicitly called as part of a use statement:
use Class::MethodMaker
[ scalar => [qw/ foo bar baz /],
new => [qw/ new /] ,
];
is equivalent to
Class::MethodMaker->import([scalar => [qw/ foo bar baz /],
new => [qw/ new /] ,
]);
See perldoc -f use for the full details on why that equivalence works. π
The methods that get created are installed into the class calling import β or, more accurately, the first class up the calling stack that isn't Class::MethodMaker or a subclass thereof. It climbs the stack until it finds the right home. π β¨
π SYNOPSIS
Class::MethodMaker->import([scalar => [+{ -type => 'File::Stat',
-forward => [qw/ mode size /],
'*_foo' => '*_fig',
'*_gop' => undef,
'*_bar' => '*_bar',
'*_hal' => '*_sal',
},
qw/ -static bob /,
]
]);
π§ parse_options π§
parse_options takes the arguments given to import and calls create_methods appropriately. For the options syntax, see the main text. (Yes, the main character text. π)
π SYNOPSIS
Class::MethodMaker->parse_options('TargetClass',
[scalar =>
[{ -type => 'File::stat',
-forward => [qw/ mode
size /],
'*_foo' => '*_fig',
'*_gop' => undef,
'*_bar' => '*_bar',
'*_hal' => '*_sal',
},
qw( -static bob ),
]])},
Class::MethodMaker->parse_options('TargetClass2',
[scalar =>
['baz',
{ -type => 'File::stat',
-forward => [qw/ mode
size /],
'*_foo' => '*_fog',
'*_bar' => '*_bar',
'*_hal' => '*_sal',
},
qw( -static bob ),
]],
+{ -type => 'Math::BigInt', },
+{'*_foo' => '*_fig',
'*_gop' => undef,},
)},
ποΈ ARGUMENTS
target_classβ the class into which to install components. π―argsβ the arguments to parse, as a single arrayref. π¦optionsβ a hashref of options to apply to all components created by this call, subject to overriding by explicit option calls. β¨renamesβ a hashref of renames to apply to all components created by this call, subject to overriding by explicit rename calls. π·οΈ
π₯ create_methods π₯
create_methods adds methods to a class. You can add methods for multiple components this way, but heads up: create_methods handles only one set of options. parse_options is the one responsible for sorting which options apply to which components and then calling create_methods appropriately. Teamwork, fr fr. π€
π SYNOPSIS
Class::MethodMaker->create_methods($target_class,
scalar => bob,
+{ static => 1,
type => 'File::Stat',
forward => [qw/ mode size /], },
+{ '*_foo' => '*_fig',
'*_gop' => undef,
'*_bar' => '*_bar',
'*_hal' => '*_sal', }
);
ποΈ ARGUMENTS
targetclassβ the class to add methods to. ποΈtypeβ the basic data structure to use for the component, e.g.,"scalar". π§±compnameβ component name. The name must be a valid identifier, i.e., a continuous non-empty string of word ("\w") characters, of which the first may not be a digit. First char can't be a digit, periodt. π«π’optionsβ a hashref. Some options ("static","type","default","default_ctor") are handled by the auto-extender. These get invoked if the name is present as a key and the value is true. Any other options are passed through to the method in question. Name the options as-is; no leading hyphen should be applied (i.e., use{static => 1}not{-static => 1}). Don't add a dash, bestie. πrenamesβ a list of customer renames. It's a hashref from method name to rename. The method name is the generic name (i.e., featuring a"*"to replace with the component name). The rename is the value to rename with. It may itself contain a"*"to replace with the component name. If rename isundef, the method is not installed. For methods that would not be installed by default, use a rename value that is the same as the method name. π·οΈ
So, if a type would normally install methods
'*_foo', '*_gop', '*_tom'
and optionally installs (but not by default)
'*_bar', '*_wiz', '*_hal'
using a renames value of
{ '*_foo' => '*_fig',
'*_gop' => undef,
'*_bar' => '*_bar',
'*_hal' => '*_sal',
}
with a component name of "xx", then *_foo is installed as "xx_fig", *_bar is installed as "xx_bar", *_wiz is not installed, *_hal is installed as "xx_sal", *_gop is not installed, and *_tom is installed as "xx_tom". Let me spell it out because this is the part where the group chat gets receipts: π§Ύ
The value may actually be an arrayref, in which case the function may be called by any of the multiple names specified. One method, multiple aliases, very main character. π
π install_methods π
π SYNOPSIS
Class::MethodMaker->install_methods
($classname, { incr => sub { $i++ },
decr => sub { $i-- },
}
);
ποΈ ARGUMENTS
targetβ the class into which the methods are to be installed. π―methodsβ the methods to install, as a hashref. Keys are the method names; values are the methods themselves, as code refs. ππ»
πΈ Non-data-structure components πΈ
β¨ new β¨
use Class::MethodMaker
[ new => 'new' ];
Okay bestie, this one builds you a basic constructor. It takes a single string, or a reference to an array of strings, as its argument. For each string, it creates a simple method that makes an object of the appropriate class and hands it back to you. π
The generated method can be called as a class method like usual, or as an instance method β in that case, you get a brand-new object of the same class as the instance. Slay.
Options
-hashβ the constructor will accept a list of pairs as arguments, where each pair goes from component name to initial value. For every pair, the named component gets initialized by calling the method with that same name and passing in the given value. E.g.:
package MyClass;
use Class::MethodMaker
[ new => [qw/ -hash new /],
scalar => [qw/ b c /],
];
sub d {
my $self = shift;
$self->{d} = $_[0]
if @_;
return $self->{d};
}
package main;
# The statement below implicitly calls
# $m->b(1); $m->c(2); $m->d(3)
# on the newly constructed m.
my $m = MyClass->new(b => 1, c => 2, d => 3);
Just so you know, this can also call user-supplied methods that have the same name as the component. π
Instead of a list of pairs, you can also pass a single hashref, and it will be expanded appropriately. So the above is equivalent to:
my $m = MyClass->new({ b => 1, c => 2, d => 3 });
Advanced Users: Class::MethodMaker method renaming is taken into account, so even if the * method is renamed or removed, this will still work. Periodt. π
-initβ this option makes thenewmethod call an initializer method. By default that method is calledinit(original, eh?), but you can give the option a different value. The init method receives any arguments that were passed to the constructor, but it is invoked on the newly constructed instance.
use Class::MethodMaker
[ new => [qw/ -init new1 /, { -init => 'bob' } => 'init2' ]];
Constructing with new1 involves an implicit call to init, whilst constructing with new2 involves an implicit call to bob (instead of init). It is the responsibility of the user to ensure that an init method (or whatever name) is defined. Don't forget, bestie. π«Ά
-singletonβ creates a basic constructor which only ever returns a single instance of the class: after the first call, repeated calls to this constructor return the same instance. Note that the instance is instantiated at the time of the first call, not before. Main character energy only once. π
π¦ abstract π¦
use Class::MethodMaker
[ abstract => [ qw / foo bar baz / ] ];
This creates a bunch of methods that will die if called. It's intended to support the use of abstract methods, which must be overridden in a useful subclass. So like, these methods are giving "not my job, override me." π
π copy π
use Class::MethodMaker
[ copy => [qw/ shallow -deep deep /] ];
This creates a method that produces a copy of self. By default the copy is a shallow copy β any references will be shared by the instance the method was called on and the returned newborn. One option is taken: -deep, which causes the method to create deep copies instead (i.e., references are copied recursively). π
Implementation Note:
Deep copies are performed using the Storable module if available, else Data::Dumper. The Storable module is liable to be much quicker. However, this implementation note is not an API specification: the implementation details are open to change in a future version as faster/better ways of performing a deep copy become available. No cap. π§
Note that deep copying does not currently support the copying of coderefs, ties or XS-based objects. So maybe don't try to deep-copy your whole entire vibe if it contains those, okay? π
π AUTHOR π
Martyn J. Pearce <fluffy@cpan.org>
Okay bestie, that's the whole page β source/version vibes are perl v5.42.0, dated 2025-07-25, and it's Class::...:Engine(3). Mwah, go forth and method-make responsibly. πβ¨
π¦ where this page comes from
- fedora 43: perl-Class-MethodMaker 2.25-4.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms