Ancient
view release on metacpan or search on metacpan
lib/object.pm view on Meta::CPAN
Register a custom type for use in slot specifications.
# Simple check
object::register_type('PositiveInt', sub {
my $val = shift;
return $val =~ /^\d+$/ && $val > 0;
});
# With coercion
object::register_type('TrimmedStr',
sub { defined $_[0] && !ref $_[0] }, # check
sub { my $v = shift; $v =~ s/^\s+|\s+$//g; $v } # coerce
);
# Now use in define
object::define('Counter',
'value:PositiveInt',
'label:TrimmedStr',
);
=head2 object::has_type($name)
Returns true if a type is registered (built-in or custom).
if (object::has_type('Email')) { ... }
=head2 object::list_types()
Returns arrayref of all registered type names.
my $types = object::list_types();
# ['Any', 'Defined', 'Str', 'Int', ... 'PositiveInt']
=head2 XS-Level Type Registration (for XS modules)
External XS modules can register types with C-level check functions
that bypass Perl callback overhead entirely (~5 cycles vs ~100 cycles).
=head3 C API Reference
Include C<object_types.h> in your XS module:
#include "object_types.h"
=head4 object_register_type_xs
void object_register_type_xs(pTHX_ const char *name,
ObjectTypeCheckFunc check,
ObjectTypeCoerceFunc coerce);
Register a type with C-level check and optional coercion functions.
Call from your BOOT section. The type name can then be used in
C<object::define()> slot specifications.
Parameters:
=over 4
=item * C<name> - Type name (e.g., "PositiveInt", "Email")
=item * C<check> - C function to validate values (required)
=item * C<coerce> - C function to coerce values (optional, pass NULL)
=back
=head4 ObjectTypeCheckFunc
typedef bool (*ObjectTypeCheckFunc)(pTHX_ SV *val);
Type check function signature. Return true if value passes the check.
=head4 ObjectTypeCoerceFunc
typedef SV* (*ObjectTypeCoerceFunc)(pTHX_ SV *val);
Type coercion function signature. Return the coerced value (may be
the same SV or a new mortal). Return NULL if coercion fails.
=head4 object_get_registered_type
RegisteredType* object_get_registered_type(pTHX_ const char *name);
Look up a registered type by name. Returns NULL if not found.
Useful for introspection or chaining type checks.
=head3 Complete Example
/* MyTypes.xs */
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "object_types.h"
static bool check_positive_int(pTHX_ SV *val) {
if (!SvIOK(val) && !(SvPOK(val) && looks_like_number(val)))
return false;
return SvIV(val) > 0;
}
static bool check_email(pTHX_ SV *val) {
if (SvROK(val)) return false;
STRLEN len;
const char *pv = SvPV(val, len);
const char *at = memchr(pv, '@', len);
return at && at != pv && at != pv + len - 1;
}
static SV* coerce_trim(pTHX_ SV *val) {
STRLEN len;
const char *pv = SvPV(val, len);
const char *start = pv;
const char *end = pv + len;
while (start < end && isSPACE(*start)) start++;
while (end > start && isSPACE(*(end-1))) end--;
return sv_2mortal(newSVpvn(start, end - start));
}
MODULE = MyTypes PACKAGE = MyTypes
( run in 3.937 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )