Class-Accessor-Inherited-XS
view release on metacpan or search on metacpan
family, it's not stored as-is, but is called instead upon the first
accessor read and it's return value is stored. After that, lazy accessor
becomes a normal one of the same type. Calling an accessor as a setter
before first getter will loose it's defaultness (unless, of course, it's
a readonly one).
constructor can create objects either from a list or from a single
hashref. Note that if you pass a hash reference, it becomes blessed too.
If that's not what you want, pass a dereferenced copy. As a special
case, passing a single undef returns you an empty object.
__PACKAGE__->new(foo => 1, bar => 2); # values are copied
__PACKAGE__->new(\%args); # values are not copied, much faster
$obj->new(foo => 1, bar => 2); # values are copied, but nothing is taken from $obj
$obj->new(\%args); # values are not copied, and nothing is taken from $obj
UTF-8 AND BINARY SAFETY
Starting with the perl 5.16.0, this module provides full support for
UTF-8 method names and hash keys. But on older perls you can't
distinguish UTF-8 strings from bytes string in method names, so
accessors with UTF-8 names can end up getting a wrong value. You have
been warned.
Also, starting from 5.16.0 accessor installation is binary safe, except
for the Windows platform. This module croaks on attempts to install
binary accessors on unsupported platforms.
THREADS
Though highly discouraged, perl threads are supported by
Class::Accessor::Inherited::XS. You can have accessors with same names
pointing to different keys in different threads, etc. There are no known
conceptual leaks.
PERFORMANCE
Class::Accessor::Inherited::XS is at least 10x times faster than
Class::Accessor::Grouped, depending on your usage pattern. Inherited
accessors have constant speed even in large inheritance chains. Object
accessors are even faster than Class::XSAccessor ones.
Accessors with just an empty sub callback are ~3x times slower then
normal ones, so use them only when absolutely necessary.
You can see some benchmarks by running bench/bench.pl
EXTENDING
package MyAccessor;
# 'register_type' isn't exported
use Class::Accessor::Inherited::XS::Constants;
Class::Accessor::Inherited::XS::register_type(
inherited_cb => {on_read => sub {}, on_write => sub{}, opts => $bitset},
);
package MyClass;
use MyAccessor;
use Class::Accessor::Inherited::XS {
inherited => ['foo'],
inherited_cb => ['bar'],
};
You can register new inherited accessor types with associated read/write
callbacks. Unlike Class::Accessor::Grouped, only a single callback can
be set for a type, without per-class get_$type/set_$type lookups. You
can omit either on_read or on_write if you don't need it to avoid
performance losses from associated call.
on_read callback receives a single argument - return value from the
underlying inherited accessor. It's result is the new accessor's return
value (and it isn't stored anywhere).
on_write callback receives original accessor's arguments, and it's
return value is stored as usual. Exceptions thrown from this callback
will cancel store and will leave old value unchanged.
You can specify additional flags with the 'opts' key. Currently only
IsNamed is supported - with it the accessor callback is invoked with
it's name passed as an additional argument. This can be useful when
creating a proxy.
PROFILING WITH Devel::NYTProf
To perform it's task, Devel::NYTProf hooks into the perl interpreter by
replacing default behaviour for subroutine calls at the opcode level. To
squeeze last bits of performance, Class::Accessor::Inherited::XS does
the same, but separately on each call site of its accessors. It turns
out into CAIX favor - Devel::NYTProf sees only the first call to CAIX
accessor, but all subsequent ones become invisible to the subs profiler.
Note that the statement profiler still correctly accounts for the time
spent on each line, you just don't see time spent in accessors' calls
separately. That's sometimes OK, sometimes not - you get profile with
all possible optimizations on, but it's not easy to comprehend.
Since it's hard to detect Devel::NYTProf (and any other module doing
such magic) in a portable way (all hail Win32), there's an %ENV switch
available - you can set CAIXS_DISABLE_ENTERSUB to a true value to
disable opcode optimizations and get a full subs profile.
CAVEATS
When using varclass accessors, do not clear or alias
*__PACKAGE__::accessor glob - that will break aliasing between accessor
storage and $__PACKAGE__::accessor variable. While the stored value is
still accessible through accessor, it effectively becomes a class one.
SEE ALSO
* Class::Accessor::Grouped
* Class::XSAccessor
COPYRIGHT AND LICENSE
Copyright (C) 2009 by Vladimir Timofeev
Copyright (C) 2014-2018 by Sergey Aleynikov
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself, either Perl version 5.10.1 or, at
your option, any later version of Perl 5 you may have available.
( run in 1.094 second using v1.01-cache-2.11-cpan-39bf76dae61 )