NAME
Class::XSConstructor - a super-fast (but limited) constructor in XS
SYNOPSIS
package Person {
use Class::XSConstructor qw( name! age email phone );
use Class::XSAccessor {
accessors => [qw( name age email phone )],
exists_predicates => [qw( age email phone )],
};
}
DESCRIPTION
Class::XSAccessor is able to provide you with a constructor for your class, but it's fairly limited. It basically just does:
sub new {
my $class = shift;
bless { @_ }, ref($class)||$class;
}
Class::XSConstructor goes a little further towards Moose-like constructors, adding the following features:
Supports initialization from a hashref as well as a list of key-value pairs.
Only initializes the attributes you specified. Given the example in the synposis:
my $obj = Person->new(name => "Alice", height => "170 cm");
The height will be ignored because it's not a defined attribute for the class.
Supports required attributes using an exclamation mark. The name attribute in the synopsis is required.
Provides support for type constraints.
use Types::Standard qw(Str Int); use Class::XSConstructor ( "name!" => Str, "age" => Int, "email" => Str, "phone" => Str, );
Type constraints can also be provided as coderefs returning a boolean:
use Types::Standard qw(Str Int); use Class::XSConstructor ( "name!" => Str, "age" => Int, "email" => sub { !ref($_[0]) and $_[0] =~ /\@/ }, "phone" => Str, );
Type constraints are likely to siginificantly slow down your constructor.
Note that Class::XSConstructor is only building your constructor for you. For read-write attributes, checking the type constraint in the accessor is your responsibility.
Supports Moose/Moo/Class::Tiny-style
BUILD
methods.Including
__no_BUILD__
.
API
This section documents the API of Class::XSConstructor for other modules that wish to wrap its functionality (to perhaps provide additional features like accessors). If you are just using Class::XSConstructor to install a constructor into your class, you can skip this section of the documentation.
Functions and Methods
None of the following functions are exported.
Class::XSConstructor->import(@optlist)
-
Does all the setup for a class to install the constructor. Will determine which class to install the constructor into based on
caller
. You can override this using:local $Class::XSConstructor::SETUP_FOR = "Some::Class::Name";
Returns nothing.
Class::XSConstructor::install_constructor($subname)
-
Just installs the XS constructor without doing some of the necessary setup.
$subname
is a fully qualified sub name, like "Foo::new".This is automatically done as part of
import
, so if you're usingimport
, you don't need to do this.Returns nothing.
Class::XSConstructor::inheritance_stuff($classname)
-
Checks the
@ISA
variable in the class and makes Class::XSConstructor aware of any attributes declared by parent classes. (Though only if those parent classes use Class::XSConstructor.)This is automatically done as part of
import
, so if you're usingimport
, you don't need to do this.Returns nothing.
($ar_has, $ar_required, $hr_isa, $sr_build) = Class::XSConstructor::get_vars($classname)
-
Returns references to the variables where Class::XSConstructor stores its configuration for the class.
Class::XSConstructor::populate_build($classname)
-
This will need to be called if the list of
BUILD
methods that ought to be called when constructing an object of the given class changes at runtime. (Which would be pretty unusual.)Returns nothing.
Use of Package Variables
Class::XSConstructor stores its configuration for class Foo in the following global variables:
@Foo::__XSCON_HAS
-
A list of all attributes which the constructor should accept (both required and optional), including attributes defined by parent classes.
inheritance_stuff
will automatically populate this from parent classes, andimport
(which callsinheritance_stuff
) will populate it based on@optlist
. @Foo::__XSCON_REQUIRED
-
A list of all attributes which the constructor should require, including attributes defined by parent classes.
inheritance_stuff
will automatically populate this from parent classes, andimport
(which callsinheritance_stuff
) will populate it based on@optlist
. %Foo::__XSCON_ISA
-
A map of attributes to type constraint coderefs, including attributes defined by parent classes. Type constraints must be coderefs, not Type::Tiny objects.
inheritance_stuff
will automatically populate this from parent classes, andimport
(which callsinheritance_stuff
) will populate it based on@optlist
, including converting type constraint objects to coderefs. $Foo::__XSCON_BUILD
-
If set to "0", indicates that XSConstructor should not try to call
BUILD
methods for the class (probably because there are none, so it would be a waste of time scanning through the inheritance tree looking for them).If set to an arrayref of coderefs, these will be the methods which the constructor calls.
If set to undef, the constructor will populate this method with either the value "0" or an arrayref of coderefs next time it is called.
Any other value is invalid.
import
will set this to undef.
If these package variables have not been declared, there is a very good chance that the constructor will segfault. import
will automatically declare and populate them for you. get_vars
will declare them and return a list of references to them.
Although you can set up Class::XSConstructor by fiddling with these package variables and then installing the constructor sub, it will probably be easier to use import
. For MooX::XSConstructor, even though I'm obviously intimately familiar with the internals of Class::XSConstructor, I just translate the Moo attribute definitions into something suitable for @optlist
, set $SETUP_FOR
, then call import
.
CAVEATS
Inheritance will automatically work if you are inheriting from another Class::XSConstructor class, but you need to set @ISA
before importing from Class::XSConstructor (which will happen at compile time!)
An easy way to do this is to use parent before using Class::XSConstructor.
package Employee {
use parent "Person";
use Class::XSConstructor qw( employee_id! );
use Class::XSAccessor { getters => [qw(employee_id)] };
}
BUGS
Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=Class-XSConstructor.
SEE ALSO
Class::Tiny, Class::XSAccessor.
AUTHOR
Toby Inkster <tobyink@cpan.org>.
THANKS
To everybody in #xs on irc.perl.org.
COPYRIGHT AND LICENCE
This software is copyright (c) 2018-2019 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
DISCLAIMER OF WARRANTIES
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.