NAME Class::Accessor::Inherited::XS - Fast XS inherited and class accessors SYNOPSIS #install accessors at compile time use Class::Accessor::Inherited::XS inherited => [qw/foo bar/], # inherited accessors with key names equal to accessor names class => [qw/baz/], # an anonymous non-inherited accessor for __PACKAGE__ varclass => [qw/boo/], # non-inherited accessor for __PACKAGE__, aliased with 'our $boo' variable ; use Class::Accessor::Inherited::XS { # optional braces inherited => { bar => 'bar_key', foo => 'foo_key', }, class => ['baz'], varclass => ['boo'], }; #or in a Class::Accessor::Grouped-like fashion use parent 'Class::Accessor::Inherited::XS'; __PACKAGE__->mk_inherited_accessors('foo', ['bar', 'bar_key']); __PACKAGE__->mk_class_accessors('baz'); __PACKAGE__->mk_varclass_accessors('boo'); DESCRIPTION This module provides a very fast implementation for 'inherited' accessors, that were introduced by the Class::Accessor::Grouped module. They give you a capability to override values set in a parent class with values set in childs or object instances. Generated accessors are compatible with Class::Accessor::Grouped generated ones. Since this module focuses primary on speed, it provides no means to have your own per-class getters/setters logic (like overriding get_inherited/set_inherited in Class::Accessor::Grouped), but it allows you to register a single get/set callback per accessor type. It also provides two types of non-inherited accessors, 'class' and 'varclass', which give you values from a package they were defined in, even when called on objects. The difference between them is that the 'varclass' internal storage is a package variable with the same name, while 'class' stores it's value in an anonymous variable. 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. From 5.16.0 and onwards, accessors installation is also 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 may 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. Accessing data from a parent in a large inheritance chain is still the worst case, but even there Class::Accessor::Inherited::XS beats Class::Accessor::Grouped best-case. Accessors with just an empty sub callback are ~3x times slower then normal ones, so use them only when you definitely need them. You can see some benchmarks by running bench/bench.pl EXTENDING package MyAccessor; # 'register_type' isn't exported Class::Accessor::Inherited::XS::register_type( inherited_cb => {on_read => sub {}, on_write => sub{}}, ); package MyClass; use MyAccessor; use Class::Accessor::Inherited::XS { inherited => ['foo'], inherited_cb => ['bar'], }; #or in a Class::Accessor::Grouped-like fashion __PACKAGE__->mk_type_accessors(inherited_cb => 'foo', 'bar'); You can register new inherited accessor types with associated read/write callbacks. Unlike Class::Accessor::Grouped, only a single callback is set for a type, without per-class get_*/set_* lookups. on_read callback gets a single argument - from a normal 'inherited' accessor. It's return value is the new accessor's return value (and is not stored anywhere). on_write callback gets two arguments - original args from the accessor's call. It's return value is saved instead of the user's supplied one. Exceptions thrown from this callback will cancel store and leave the old value unchanged. PROFILING WITH Devel::NYTProf To perform it's task, Devel::NYTProf hooks into the perl interpreter by replacing default behaviour for calling subroutines on 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 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 optimization and get a full subs profile. SEE ALSO * Class::Accessor::Grouped * Class::XSAccessor COPYRIGHT AND LICENSE Copyright (C) 2009 by Vladimir Timofeev Copyright (C) 2014-2015 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.