| Filename | /usr/share/perl5/Class/Accessor/Grouped.pm |
| Statements | Executed 150581 statements in 673ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 927 | 1 | 1 | 370ms | 420ms | Class::Accessor::Grouped::__ANON__[:774] |
| 21437 | 2 | 2 | 206ms | 261ms | Class::Accessor::Grouped::get_inherited |
| 1921 | 1 | 1 | 78.9ms | 629ms | Class::Accessor::Grouped::_mk_group_accessors |
| 3938 | 1 | 1 | 46.7ms | 490ms | Class::Accessor::Grouped::__ANON__[:942] |
| 3179 | 1 | 1 | 27.6ms | 37.9ms | Class::Accessor::Grouped::get_super_paths |
| 3938 | 1 | 1 | 27.2ms | 517ms | Class::Accessor::Grouped::make_group_accessor |
| 1921 | 19 | 10 | 13.3ms | 642ms | Class::Accessor::Grouped::mk_group_accessors |
| 927 | 1 | 1 | 6.40ms | 8.87ms | Class::Accessor::Grouped::__ANON__[:708] |
| 3939 | 3 | 1 | 5.02ms | 5.02ms | Class::Accessor::Grouped::CORE:match (opcode) |
| 927 | 1 | 1 | 2.47ms | 2.47ms | __CAG_ENV__::perlstring |
| 720 | 4 | 4 | 2.41ms | 2.53ms | Class::Accessor::Grouped::set_inherited |
| 650 | 2 | 1 | 846µs | 846µs | DBIx::Class::ResultSource::CORE:match (opcode) |
| 1602 | 1 | 1 | 557µs | 557µs | DBIx::Class::ResultSource::CORE:subst (opcode) |
| 1 | 1 | 1 | 85µs | 206µs | DBIx::Class::Storage::DBI::on_connect_call |
| 1 | 1 | 1 | 63µs | 2.20ms | Class::Accessor::Grouped::BEGIN@31 |
| 3 | 3 | 2 | 59µs | 169µs | DBIx::Class::Storage::DBI::_dbh_autocommit |
| 5 | 4 | 2 | 53µs | 162µs | DBIx::Class::ResultSet::_result_class |
| 1 | 1 | 1 | 50µs | 163µs | DBIx::Class::Storage::DBI::disable_sth_caching |
| 1 | 1 | 1 | 49µs | 167µs | DBIx::Class::Storage::schema |
| 1 | 1 | 1 | 48µs | 155µs | DBIx::Class::ResultSource::source_name |
| 1 | 1 | 1 | 48µs | 190µs | DBIx::Class::ResultSource::name |
| 8 | 7 | 2 | 46µs | 119µs | DBIx::Class::ResultSet::result_source |
| 1 | 1 | 1 | 42µs | 122µs | DBIx::Class::ResultSource::_relationships |
| 1 | 1 | 1 | 41µs | 882µs | DBIx::Class::ResultSource::_primaries |
| 3 | 3 | 2 | 41µs | 112µs | DBIx::Class::Storage::DBI::_conn_pid |
| 1 | 1 | 1 | 40µs | 124µs | DBIx::Class::Storage::debug |
| 3 | 3 | 2 | 39µs | 91µs | DBIx::Class::Storage::DBI::_driver_determined |
| 4 | 4 | 2 | 35µs | 102µs | DBIx::Class::Storage::DBI::_sql_maker_opts |
| 6 | 6 | 2 | 35µs | 97µs | DBIx::Class::Storage::DBI::_dbh_details |
| 11 | 10 | 3 | 35µs | 96µs | DBIx::Class::Storage::DBI::_dbh |
| 1 | 1 | 1 | 35µs | 96µs | DBIx::Class::ResultSource::_columns |
| 1 | 1 | 1 | 34µs | 120µs | DBIx::Class::Row::in_storage |
| 1 | 1 | 1 | 34µs | 102µs | DBIx::Class::Storage::transaction_depth |
| 3 | 3 | 3 | 33µs | 94µs | DBIx::Class::Storage::DBI::_dbic_connect_attributes |
| 1 | 1 | 1 | 31µs | 96µs | DBIx::Class::ResultSource::_unique_constraints |
| 3 | 3 | 2 | 31µs | 111µs | DBIx::Class::Storage::DBI::_connect_info |
| 5 | 5 | 2 | 31µs | 86µs | DBIx::Class::Storage::DBI::_sql_maker |
| 3 | 3 | 2 | 31µs | 91µs | DBIx::Class::Storage::DBI::on_connect_do |
| 1 | 1 | 1 | 30µs | 98µs | DBIx::Class::ResultSource::_ordered_columns |
| 3 | 3 | 2 | 28µs | 85µs | DBIx::Class::Storage::DBI::unsafe |
| 1 | 1 | 1 | 13µs | 20µs | Class::Accessor::Grouped::BEGIN@2 |
| 1 | 1 | 1 | 12µs | 19µs | Class::Accessor::Grouped::BEGIN@87 |
| 1 | 1 | 1 | 11µs | 24µs | Class::Accessor::Grouped::BEGIN@378 |
| 1 | 1 | 1 | 11µs | 16µs | Class::Accessor::Grouped::BEGIN@894 |
| 1 | 1 | 1 | 10µs | 17µs | Class::Accessor::Grouped::BEGIN@872 |
| 2 | 2 | 1 | 10µs | 10µs | DBIx::Class::Storage::DBI::CORE:match (opcode) |
| 1 | 1 | 1 | 9µs | 15µs | Class::Accessor::Grouped::BEGIN@377 |
| 1 | 1 | 1 | 9µs | 19µs | Class::Accessor::Grouped::BEGIN@895 |
| 1 | 1 | 1 | 9µs | 15µs | Class::Accessor::Grouped::BEGIN@418 |
| 1 | 1 | 1 | 9µs | 20µs | Class::Accessor::Grouped::BEGIN@88 |
| 1 | 1 | 1 | 7µs | 10µs | Class::Accessor::Grouped::BEGIN@3 |
| 1 | 1 | 1 | 6µs | 6µs | Class::Accessor::Grouped::BEGIN@8 |
| 1 | 1 | 1 | 4µs | 4µs | Class::Accessor::Grouped::BEGIN@6 |
| 1 | 1 | 1 | 4µs | 4µs | Class::Accessor::Grouped::BEGIN@4 |
| 1 | 1 | 1 | 3µs | 3µs | Class::Accessor::Grouped::BEGIN@23 |
| 1 | 1 | 1 | 3µs | 3µs | Class::Accessor::Grouped::BEGIN@5 |
| 2 | 2 | 1 | 1µs | 1µs | __CAG_ENV__::__ANON__ (xsub) |
| 1 | 1 | 1 | 600ns | 600ns | DBIx::Class::Storage::DBI::schema (xsub) |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::CLONE |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::__ANON__[:728] |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::__ANON__[:748] |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::__ANON__[:914] |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::get_component_class |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::get_simple |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::make_group_ro_accessor |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::make_group_wo_accessor |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::mk_group_ro_accessors |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::mk_group_wo_accessors |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::set_component_class |
| 0 | 0 | 0 | 0s | 0s | Class::Accessor::Grouped::set_simple |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSet::__result_class_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSet::_result_source_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::__columns_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::__ordered_columns_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::__primaries_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::__relationships_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::__unique_constraints_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::_column_info_from_storage_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::_name_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::_resultset_attributes_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::_source_info_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::_source_name_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::column_info_from_storage |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::resultset_attributes |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSource::source_info |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSourceHandle::__detached_source_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSourceHandle::_detached_source |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSourceHandle::_schema_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSourceHandle::_source_moniker_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSourceHandle::schema |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSourceHandle::source_moniker |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Row::_in_storage_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::_limit_dialect_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::_name_sep_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::_quote_char_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::limit_dialect |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::name_sep |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::SQLMaker::quote_char |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__autoinc_supplied_for_op_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__conn_pid_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__connect_info_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__dbh_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__dbh_autocommit_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__dbh_details_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__dbic_connect_attributes_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__driver_determined_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__perform_autoinc_retrieval_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__sql_maker_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::__sql_maker_opts_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_auto_savepoint_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_autoinc_supplied_for_op |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_disable_sth_caching_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_on_connect_call_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_on_connect_do_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_on_disconnect_call_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_on_disconnect_do_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_perform_autoinc_retrieval |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::_unsafe_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::auto_savepoint |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::on_disconnect_call |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::DBI::on_disconnect_do |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::_auto_savepoint_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::_debug_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::_savepoints_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::_schema_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::_transaction_depth_accessor |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::auto_savepoint |
| 0 | 0 | 0 | 0s | 0s | DBIx::Class::Storage::savepoints |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Class::Accessor::Grouped; | ||||
| 2 | 2 | 34µs | 2 | 26µs | # spent 20µs (13+7) within Class::Accessor::Grouped::BEGIN@2 which was called:
# once (13µs+7µs) by base::import at line 2 # spent 20µs making 1 call to Class::Accessor::Grouped::BEGIN@2
# spent 6µs making 1 call to strict::import |
| 3 | 2 | 25µs | 2 | 14µs | # spent 10µs (7+4) within Class::Accessor::Grouped::BEGIN@3 which was called:
# once (7µs+4µs) by base::import at line 3 # spent 10µs making 1 call to Class::Accessor::Grouped::BEGIN@3
# spent 4µs making 1 call to warnings::import |
| 4 | 2 | 17µs | 1 | 4µs | # spent 4µs within Class::Accessor::Grouped::BEGIN@4 which was called:
# once (4µs+0s) by base::import at line 4 # spent 4µs making 1 call to Class::Accessor::Grouped::BEGIN@4 |
| 5 | 2 | 18µs | 1 | 3µs | # spent 3µs within Class::Accessor::Grouped::BEGIN@5 which was called:
# once (3µs+0s) by base::import at line 5 # spent 3µs making 1 call to Class::Accessor::Grouped::BEGIN@5 |
| 6 | 2 | 54µs | 1 | 4µs | # spent 4µs within Class::Accessor::Grouped::BEGIN@6 which was called:
# once (4µs+0s) by base::import at line 6 # spent 4µs making 1 call to Class::Accessor::Grouped::BEGIN@6 |
| 7 | |||||
| 8 | # spent 6µs within Class::Accessor::Grouped::BEGIN@8 which was called:
# once (6µs+0s) by base::import at line 16 | ||||
| 9 | # use M::R to work around the 5.8 require bugs | ||||
| 10 | 1 | 7µs | if ($] < 5.009_005) { | ||
| 11 | Module::Runtime::require_module('MRO::Compat'); | ||||
| 12 | } | ||||
| 13 | else { | ||||
| 14 | 1 | 700ns | require mro; | ||
| 15 | } | ||||
| 16 | 1 | 66µs | 1 | 6µs | } # spent 6µs making 1 call to Class::Accessor::Grouped::BEGIN@8 |
| 17 | |||||
| 18 | 1 | 900ns | our $VERSION = '0.10012'; | ||
| 19 | 1 | 11µs | 1 | 3µs | $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases # spent 3µs making 1 call to Class::Accessor::Grouped::CORE:match |
| 20 | |||||
| 21 | # when changing minimum version don't forget to adjust Makefile.PL as well | ||||
| 22 | 1 | 300ns | our $__minimum_xsa_version; | ||
| 23 | 1 | 301µs | 1 | 3µs | # spent 3µs within Class::Accessor::Grouped::BEGIN@23 which was called:
# once (3µs+0s) by base::import at line 23 # spent 3µs making 1 call to Class::Accessor::Grouped::BEGIN@23 |
| 24 | |||||
| 25 | 1 | 100ns | our $USE_XS; | ||
| 26 | # the unless defined is here so that we can override the value | ||||
| 27 | # before require/use, *regardless* of the state of $ENV{CAG_USE_XS} | ||||
| 28 | 1 | 2µs | $USE_XS = $ENV{CAG_USE_XS} | ||
| 29 | unless defined $USE_XS; | ||||
| 30 | |||||
| 31 | # spent 2.20ms (63µs+2.13) within Class::Accessor::Grouped::BEGIN@31 which was called:
# once (63µs+2.13ms) by base::import at line 75 | ||||
| 32 | package # hide from PAUSE | ||||
| 33 | __CAG_ENV__; | ||||
| 34 | |||||
| 35 | 1 | 200ns | die "Huh?! No minimum C::XSA version?!\n" | ||
| 36 | unless $__minimum_xsa_version; | ||||
| 37 | |||||
| 38 | 1 | 200ns | local $@; | ||
| 39 | 1 | 2µs | require constant; | ||
| 40 | |||||
| 41 | # individual (one const at a time) imports so we are 5.6.2 compatible | ||||
| 42 | # if we can - why not ;) | ||||
| 43 | 1 | 44µs | 1 | 38µs | constant->import( NO_SUBNAME => eval { # spent 38µs making 1 call to constant::import |
| 44 | 1 | 30µs | 1 | 24µs | Module::Runtime::require_module('Sub::Name') # spent 24µs making 1 call to Module::Runtime::require_module |
| 45 | } ? 0 : "$@" ); | ||||
| 46 | |||||
| 47 | 1 | 100ns | my $found_cxsa; | ||
| 48 | 1 | 41µs | 2 | 29µs | constant->import( NO_CXSA => ( NO_SUBNAME() || ( eval { # spent 28µs making 1 call to constant::import
# spent 600ns making 1 call to __CAG_ENV__::__ANON__ |
| 49 | 1 | 95µs | 1 | 2.00ms | Module::Runtime::require_module('Class::XSAccessor'); # spent 2.00ms making 1 call to Module::Runtime::require_module |
| 50 | 1 | 17µs | 1 | 8µs | $found_cxsa = Class::XSAccessor->VERSION; # spent 8µs making 1 call to version::vxs::_VERSION |
| 51 | 1 | 7µs | 1 | 4µs | Class::XSAccessor->VERSION($__minimum_xsa_version); # spent 4µs making 1 call to version::vxs::_VERSION |
| 52 | } ? 0 : "$@" ) ) ); | ||||
| 53 | |||||
| 54 | 1 | 4µs | 1 | 600ns | if (NO_CXSA() and $found_cxsa and !$ENV{CAG_OLD_XS_NOWARN}) { # spent 600ns making 1 call to __CAG_ENV__::__ANON__ |
| 55 | warn( | ||||
| 56 | 'The installed version of Class::XSAccessor is too old ' | ||||
| 57 | . "(v$found_cxsa < v$__minimum_xsa_version). Please upgrade " | ||||
| 58 | . "to instantly quadruple the performance of 'simple' accessors. " | ||||
| 59 | . 'Set $ENV{CAG_OLD_XS_NOWARN} if you wish to disable this ' | ||||
| 60 | . "warning.\n" | ||||
| 61 | ); | ||||
| 62 | } | ||||
| 63 | |||||
| 64 | 1 | 18µs | 1 | 13µs | constant->import( BROKEN_GOTO => ($] < '5.008009') ? 1 : 0 ); # spent 13µs making 1 call to constant::import |
| 65 | |||||
| 66 | 1 | 14µs | 1 | 10µs | constant->import( UNSTABLE_DOLLARAT => ($] < '5.013002') ? 1 : 0 ); # spent 10µs making 1 call to constant::import |
| 67 | |||||
| 68 | 1 | 16µs | 1 | 9µs | constant->import( TRACK_UNDEFER_FAIL => ( # spent 9µs making 1 call to constant::import |
| 69 | $INC{'Test/Builder.pm'} || $INC{'Test/Builder2.pm'} | ||||
| 70 | and | ||||
| 71 | $0 =~ m{ ^ (?: \. \/ )? x?t / .+ \.t $}x | ||||
| 72 | ) ? 1 : 0 ); | ||||
| 73 | |||||
| 74 | 927 | 2.83ms | # spent 2.47ms within __CAG_ENV__::perlstring which was called 927 times, avg 3µs/call:
# 927 times (2.47ms+0s) by Class::Accessor::Grouped::__ANON__[/usr/share/perl5/Class/Accessor/Grouped.pm:708] at line 700, avg 3µs/call | ||
| 75 | 1 | 88µs | 1 | 2.20ms | } # spent 2.20ms making 1 call to Class::Accessor::Grouped::BEGIN@31 |
| 76 | |||||
| 77 | # Yes this method is undocumented | ||||
| 78 | # Yes it should be a private coderef like all the rest at the end of this file | ||||
| 79 | # No we can't do that (yet) because the DBIC-CDBI compat layer overrides it | ||||
| 80 | # %$*@!?&!&#*$!!! | ||||
| 81 | |||||
| 82 | 1 | 200ns | my $illegal_accessors_warned; | ||
| 83 | # spent 629ms (78.9+550) within Class::Accessor::Grouped::_mk_group_accessors which was called 1921 times, avg 327µs/call:
# 1921 times (78.9ms+550ms) by Class::Accessor::Grouped::mk_group_accessors at line 251, avg 327µs/call | ||||
| 84 | 1921 | 1.00ms | my($self, $maker, $group, @fields) = @_; | ||
| 85 | 1921 | 802µs | my $class = length (ref ($self) ) ? ref ($self) : $self; | ||
| 86 | |||||
| 87 | 2 | 53µs | 2 | 26µs | # spent 19µs (12+7) within Class::Accessor::Grouped::BEGIN@87 which was called:
# once (12µs+7µs) by base::import at line 87 # spent 19µs making 1 call to Class::Accessor::Grouped::BEGIN@87
# spent 7µs making 1 call to strict::unimport |
| 88 | 2 | 678µs | 2 | 31µs | # spent 20µs (9+11) within Class::Accessor::Grouped::BEGIN@88 which was called:
# once (9µs+11µs) by base::import at line 88 # spent 20µs making 1 call to Class::Accessor::Grouped::BEGIN@88
# spent 11µs making 1 call to warnings::unimport |
| 89 | |||||
| 90 | # So we don't have to do lots of lookups inside the loop. | ||||
| 91 | 1921 | 22.5ms | 1921 | 9.11ms | $maker = $self->can($maker) unless ref $maker; # spent 9.11ms making 1921 calls to UNIVERSAL::can, avg 5µs/call |
| 92 | |||||
| 93 | 1921 | 4.84ms | for (@fields) { | ||
| 94 | |||||
| 95 | 1969 | 1.11ms | my ($name, $field) = (ref $_) ? (@$_) : ($_, $_); | ||
| 96 | |||||
| 97 | 1969 | 11.4ms | 1969 | 4.09ms | if ($name !~ /\A[A-Z_a-z][0-9A-Z_a-z]*\z/) { # spent 4.09ms making 1969 calls to Class::Accessor::Grouped::CORE:match, avg 2µs/call |
| 98 | |||||
| 99 | if ($name =~ /\0/) { | ||||
| 100 | Carp::croak(sprintf | ||||
| 101 | "Illegal accessor name %s - nulls should never appear in stash keys", | ||||
| 102 | __CAG_ENV__::perlstring($name), | ||||
| 103 | ); | ||||
| 104 | } | ||||
| 105 | elsif (! $ENV{CAG_ILLEGAL_ACCESSOR_NAME_OK} ) { | ||||
| 106 | Carp::croak( | ||||
| 107 | "Illegal accessor name '$name'. If you want CAG to attempt creating " | ||||
| 108 | . 'it anyway (possible if Sub::Name is available) set ' | ||||
| 109 | . '$ENV{CAG_ILLEGAL_ACCESSOR_NAME_OK}' | ||||
| 110 | ); | ||||
| 111 | } | ||||
| 112 | elsif (__CAG_ENV__::NO_SUBNAME) { | ||||
| 113 | Carp::croak( | ||||
| 114 | "Unable to install accessor with illegal name '$name': " | ||||
| 115 | . 'Sub::Name not available' | ||||
| 116 | ); | ||||
| 117 | } | ||||
| 118 | elsif ( | ||||
| 119 | # Because one of the former maintainers of DBIC::SL is a raging | ||||
| 120 | # idiot, there is now a ton of DBIC code out there that attempts | ||||
| 121 | # to create column accessors with illegal names. In the interest | ||||
| 122 | # of not cluttering the logs of unsuspecting victims (unsuspecting | ||||
| 123 | # because these accessors are unusable anyway) we provide an | ||||
| 124 | # explicit "do not warn at all" escape, until all such code is | ||||
| 125 | # fixed (this will be a loooooong time >:( | ||||
| 126 | $ENV{CAG_ILLEGAL_ACCESSOR_NAME_OK} ne 'DO_NOT_WARN' | ||||
| 127 | and | ||||
| 128 | ! $illegal_accessors_warned->{$class}++ | ||||
| 129 | ) { | ||||
| 130 | Carp::carp( | ||||
| 131 | "Installing illegal accessor '$name' into $class, see " | ||||
| 132 | . 'documentation for more details' | ||||
| 133 | ); | ||||
| 134 | } | ||||
| 135 | } | ||||
| 136 | |||||
| 137 | 1969 | 3.38ms | 1969 | 931µs | Carp::carp("Having a data accessor named '$name' in '$class' is unwise.") # spent 931µs making 1969 calls to Class::Accessor::Grouped::CORE:match, avg 473ns/call |
| 138 | if $name =~ /\A(?: DESTROY | AUTOLOAD | CLONE )\z/x; | ||||
| 139 | |||||
| 140 | 1969 | 1.52ms | my $alias = "_${name}_accessor"; | ||
| 141 | |||||
| 142 | 1969 | 2.40ms | for ($name, $alias) { | ||
| 143 | |||||
| 144 | # the maker may elect to not return anything, meaning it already | ||||
| 145 | # installed the coderef for us (e.g. lack of Sub::Name) | ||||
| 146 | 3938 | 5.40ms | 3938 | 517ms | my $cref = $self->$maker($group, $field, $_) # spent 517ms making 3938 calls to Class::Accessor::Grouped::make_group_accessor, avg 131µs/call |
| 147 | or next; | ||||
| 148 | |||||
| 149 | 3938 | 2.58ms | my $fq_meth = "${class}::$_"; | ||
| 150 | |||||
| 151 | 3938 | 54.5ms | 3938 | 18.7ms | *$fq_meth = Sub::Name::subname($fq_meth, $cref); # spent 18.7ms making 3938 calls to Sub::Name::subname, avg 5µs/call |
| 152 | #unless defined &{$class."\:\:$field"} | ||||
| 153 | } | ||||
| 154 | } | ||||
| 155 | }; | ||||
| 156 | |||||
| 157 | # $gen_accessor coderef is setup at the end for clarity | ||||
| 158 | my $gen_accessor; | ||||
| 159 | |||||
| 160 | =head1 NAME | ||||
| 161 | |||||
| 162 | Class::Accessor::Grouped - Lets you build groups of accessors | ||||
| 163 | |||||
| 164 | =head1 SYNOPSIS | ||||
| 165 | |||||
| 166 | use base 'Class::Accessor::Grouped'; | ||||
| 167 | |||||
| 168 | # make basic accessors for objects | ||||
| 169 | __PACKAGE__->mk_group_accessors(simple => qw(id name email)); | ||||
| 170 | |||||
| 171 | # make accessor that works for objects and classes | ||||
| 172 | __PACKAGE__->mk_group_accessors(inherited => 'awesome_level'); | ||||
| 173 | |||||
| 174 | # make an accessor which calls a custom pair of getters/setters | ||||
| 175 | sub get_column { ... this will be called when you do $obj->name() ... } | ||||
| 176 | sub set_column { ... this will be called when you do $obj->name('foo') ... } | ||||
| 177 | __PACKAGE__->mk_group_accessors(column => 'name'); | ||||
| 178 | |||||
| 179 | =head1 DESCRIPTION | ||||
| 180 | |||||
| 181 | This class lets you build groups of accessors that will call different | ||||
| 182 | getters and setters. The documentation of this module still requires a lot | ||||
| 183 | of work (B<< volunteers welcome >.> >>), but in the meantime you can refer to | ||||
| 184 | L<this post|http://lo-f.at/glahn/2009/08/WritingPowerfulAccessorsForPerlClasses.html> | ||||
| 185 | for more information. | ||||
| 186 | |||||
| 187 | =head2 Notes on accessor names | ||||
| 188 | |||||
| 189 | In general method names in Perl are considered identifiers, and as such need to | ||||
| 190 | conform to the identifier specification of C<qr/\A[A-Z_a-z][0-9A-Z_a-z]*\z/>. | ||||
| 191 | While it is rather easy to invoke methods with non-standard names | ||||
| 192 | (C<< $obj->${\"anything goes"} >>), it is not possible to properly declare such | ||||
| 193 | methods without the use of L<Sub::Name>. Since this module must be able to | ||||
| 194 | function identically with and without its optional dependencies, starting with | ||||
| 195 | version C<0.10008> attempting to declare an accessor with a non-standard name | ||||
| 196 | is a fatal error (such operations would silently succeed since version | ||||
| 197 | C<0.08004>, as long as L<Sub::Name> is present, or otherwise would result in a | ||||
| 198 | syntax error during a string eval). | ||||
| 199 | |||||
| 200 | Unfortunately in the years since C<0.08004> a rather large body of code | ||||
| 201 | accumulated in the wild that does attempt to declare accessors with funny | ||||
| 202 | names. One notable perpetrator is L<DBIx::Class::Schema::Loader>, which under | ||||
| 203 | certain conditions could create accessors of the C<column> group which start | ||||
| 204 | with numbers and/or some other punctuation (the proper way would be to declare | ||||
| 205 | columns with the C<accessor> attribute set to C<undef>). | ||||
| 206 | |||||
| 207 | Therefore an escape mechanism is provided via the environment variable | ||||
| 208 | C<CAG_ILLEGAL_ACCESSOR_NAME_OK>. When set to a true value, one warning is | ||||
| 209 | issued B<per class> on attempts to declare an accessor with a non-conforming | ||||
| 210 | name, and as long as L<Sub::Name> is available all accessors will be properly | ||||
| 211 | created. Regardless of this setting, accessor names containing nulls C<"\0"> | ||||
| 212 | are disallowed, due to various deficiencies in perl itself. | ||||
| 213 | |||||
| 214 | If your code base has too many instances of illegal accessor declarations, and | ||||
| 215 | a fix is not feasible due to time constraints, it is possible to disable the | ||||
| 216 | warnings altogether by setting C<$ENV{CAG_ILLEGAL_ACCESSOR_NAME_OK}> to | ||||
| 217 | C<DO_NOT_WARN> (observe capitalization). | ||||
| 218 | |||||
| 219 | =head1 METHODS | ||||
| 220 | |||||
| 221 | =head2 mk_group_accessors | ||||
| 222 | |||||
| 223 | __PACKAGE__->mk_group_accessors(simple => 'hair_length', [ hair_color => 'hc' ]); | ||||
| 224 | |||||
| 225 | =over 4 | ||||
| 226 | |||||
| 227 | =item Arguments: $group, @fieldspec | ||||
| 228 | |||||
| 229 | Returns: none | ||||
| 230 | |||||
| 231 | =back | ||||
| 232 | |||||
| 233 | Creates a set of accessors in a given group. | ||||
| 234 | |||||
| 235 | $group is the name of the accessor group for the generated accessors; they | ||||
| 236 | will call get_$group($field) on get and set_$group($field, $value) on set. | ||||
| 237 | |||||
| 238 | If you want to mimic Class::Accessor's mk_accessors $group has to be 'simple' | ||||
| 239 | to tell Class::Accessor::Grouped to use its own get_simple and set_simple | ||||
| 240 | methods. | ||||
| 241 | |||||
| 242 | @fieldspec is a list of field/accessor names; if a fieldspec is a scalar | ||||
| 243 | this is used as both field and accessor name, if a listref it is expected to | ||||
| 244 | be of the form [ $accessor, $field ]. | ||||
| 245 | |||||
| 246 | =cut | ||||
| 247 | |||||
| 248 | # spent 642ms (13.3+629) within Class::Accessor::Grouped::mk_group_accessors which was called 1921 times, avg 334µs/call:
# 1599 times (10.2ms+556ms) by DBIx::Class::Row::register_column at line 1454 of DBIx/Class/Row.pm, avg 354µs/call
# 184 times (2.13ms+17.9ms) by DBIx::Class::mk_classaccessor at line 36 of DBIx/Class.pm, avg 109µs/call
# 122 times (796µs+36.4ms) by DBIx::Class::InflateColumn::inflate_column at line 101 of DBIx/Class/InflateColumn.pm, avg 305µs/call
# once (11µs+4.62ms) by Class::C3::Componentised::ensure_class_loaded at line 74 of DBIx/Class/Storage/DBI.pm
# once (5µs+4.57ms) by Class::C3::Componentised::ensure_class_loaded at line 73 of DBIx/Class/Storage/DBI.pm
# once (14µs+2.68ms) by Class::C3::Componentised::ensure_class_loaded at line 22 of DBIx/Class/Storage/DBI.pm
# once (9µs+2.01ms) by Class::C3::Componentised::ensure_class_loaded at line 26 of DBIx/Class/Storage/DBI.pm
# once (4µs+1.14ms) by base::import at line 23 of DBIx/Class/Storage.pm
# once (4µs+696µs) by Class::C3::Componentised::ensure_class_loaded at line 28 of DBIx/Class/ResultSource.pm
# once (14µs+556µs) by Class::C3::Componentised::ensure_class_loaded at line 21 of DBIx/Class/ResultSource.pm
# once (10µs+555µs) by Class::C3::Componentised::ensure_class_loaded at line 33 of DBIx/Class/Storage/DBI.pm
# once (12µs+434µs) by DBIx::Class::ResultSource::Table::BEGIN@6 at line 34 of DBIx/Class/ResultSet.pm
# once (16µs+357µs) by base::import at line 27 of DBIx/Class.pm
# once (8µs+348µs) by base::import at line 13 of DBIx/Class/ResultSourceProxy.pm
# once (4µs+338µs) by Class::C3::Componentised::ensure_class_loaded at line 45 of DBIx/Class/Storage/DBI.pm
# once (12µs+275µs) by base::import at line 22 of DBIx/Class/Storage.pm
# once (15µs+204µs) by base::import at line 45 of DBIx/Class/SQLMaker.pm
# once (12µs+206µs) by DBIx::Class::ResultSource::BEGIN@9 at line 15 of DBIx/Class/ResultSourceHandle.pm
# once (14µs+120µs) by base::import at line 27 of DBIx/Class/Row.pm | ||||
| 249 | 1921 | 1.21ms | my ($self, $group, @fields) = @_; | ||
| 250 | |||||
| 251 | 1921 | 8.20ms | 1921 | 629ms | $self->_mk_group_accessors('make_group_accessor', $group, @fields); # spent 629ms making 1921 calls to Class::Accessor::Grouped::_mk_group_accessors, avg 327µs/call |
| 252 | 1921 | 12.4ms | return; | ||
| 253 | } | ||||
| 254 | |||||
| 255 | =head2 mk_group_ro_accessors | ||||
| 256 | |||||
| 257 | __PACKAGE__->mk_group_ro_accessors(simple => 'birthdate', [ social_security_number => 'ssn' ]); | ||||
| 258 | |||||
| 259 | =over 4 | ||||
| 260 | |||||
| 261 | =item Arguments: $group, @fieldspec | ||||
| 262 | |||||
| 263 | Returns: none | ||||
| 264 | |||||
| 265 | =back | ||||
| 266 | |||||
| 267 | Creates a set of read only accessors in a given group. Identical to | ||||
| 268 | L</mk_group_accessors> but accessors will throw an error if passed a value | ||||
| 269 | rather than setting the value. | ||||
| 270 | |||||
| 271 | =cut | ||||
| 272 | |||||
| 273 | sub mk_group_ro_accessors { | ||||
| 274 | my($self, $group, @fields) = @_; | ||||
| 275 | |||||
| 276 | $self->_mk_group_accessors('make_group_ro_accessor', $group, @fields); | ||||
| 277 | return; | ||||
| 278 | } | ||||
| 279 | |||||
| 280 | =head2 mk_group_wo_accessors | ||||
| 281 | |||||
| 282 | __PACKAGE__->mk_group_wo_accessors(simple => 'lie', [ subject => 'subj' ]); | ||||
| 283 | |||||
| 284 | =over 4 | ||||
| 285 | |||||
| 286 | =item Arguments: $group, @fieldspec | ||||
| 287 | |||||
| 288 | Returns: none | ||||
| 289 | |||||
| 290 | =back | ||||
| 291 | |||||
| 292 | Creates a set of write only accessors in a given group. Identical to | ||||
| 293 | L</mk_group_accessors> but accessors will throw an error if not passed a | ||||
| 294 | value rather than getting the value. | ||||
| 295 | |||||
| 296 | =cut | ||||
| 297 | |||||
| 298 | sub mk_group_wo_accessors { | ||||
| 299 | my($self, $group, @fields) = @_; | ||||
| 300 | |||||
| 301 | $self->_mk_group_accessors('make_group_wo_accessor', $group, @fields); | ||||
| 302 | return; | ||||
| 303 | } | ||||
| 304 | |||||
| 305 | =head2 get_simple | ||||
| 306 | |||||
| 307 | =over 4 | ||||
| 308 | |||||
| 309 | =item Arguments: $field | ||||
| 310 | |||||
| 311 | Returns: $value | ||||
| 312 | |||||
| 313 | =back | ||||
| 314 | |||||
| 315 | Simple getter for hash-based objects which returns the value for the field | ||||
| 316 | name passed as an argument. | ||||
| 317 | |||||
| 318 | =cut | ||||
| 319 | |||||
| 320 | sub get_simple { | ||||
| 321 | $_[0]->{$_[1]}; | ||||
| 322 | } | ||||
| 323 | |||||
| 324 | =head2 set_simple | ||||
| 325 | |||||
| 326 | =over 4 | ||||
| 327 | |||||
| 328 | =item Arguments: $field, $new_value | ||||
| 329 | |||||
| 330 | Returns: $new_value | ||||
| 331 | |||||
| 332 | =back | ||||
| 333 | |||||
| 334 | Simple setter for hash-based objects which sets and then returns the value | ||||
| 335 | for the field name passed as an argument. | ||||
| 336 | |||||
| 337 | =cut | ||||
| 338 | |||||
| 339 | sub set_simple { | ||||
| 340 | $_[0]->{$_[1]} = $_[2]; | ||||
| 341 | } | ||||
| 342 | |||||
| 343 | |||||
| 344 | =head2 get_inherited | ||||
| 345 | |||||
| 346 | =over 4 | ||||
| 347 | |||||
| 348 | =item Arguments: $field | ||||
| 349 | |||||
| 350 | Returns: $value | ||||
| 351 | |||||
| 352 | =back | ||||
| 353 | |||||
| 354 | Simple getter for Classes and hash-based objects which returns the value for | ||||
| 355 | the field name passed as an argument. This behaves much like | ||||
| 356 | L<Class::Data::Accessor> where the field can be set in a base class, | ||||
| 357 | inherited and changed in subclasses, and inherited and changed for object | ||||
| 358 | instances. | ||||
| 359 | |||||
| 360 | =cut | ||||
| 361 | |||||
| 362 | # spent 261ms (206+54.3) within Class::Accessor::Grouped::get_inherited which was called 21437 times, avg 12µs/call:
# 15088 times (167ms+50.5ms) by DBIx::Class::ResultSourceProxy::Table::table_class or DBIx::Class::Schema::class_mappings or DBIx::Class::Schema::default_resultset_attributes or DBIx::Class::Schema::source_registrations or DBIx::Class::Schema::storage or DBIx::Class::Schema::storage_type or DBIx::Class::Storage::DBI::sql_limit_dialect or Koha::Objects::find or Koha::Schema::Result::Accountline::result_source_instance or Koha::Schema::Result::Accountoffset::result_source_instance or Koha::Schema::Result::ActionLog::result_source_instance or Koha::Schema::Result::ActionLogs::result_source_instance or Koha::Schema::Result::AdditionalField::result_source_instance or Koha::Schema::Result::AdditionalFieldValue::result_source_instance or Koha::Schema::Result::Alert::result_source_instance or Koha::Schema::Result::Aqbasket::result_source_instance or Koha::Schema::Result::Aqbasketgroup::result_source_instance or Koha::Schema::Result::Aqbasketuser::result_source_instance or Koha::Schema::Result::Aqbookseller::result_source_instance or Koha::Schema::Result::Aqbudget::result_source_instance or Koha::Schema::Result::Aqbudgetborrower::result_source_instance or Koha::Schema::Result::Aqbudgetperiod::result_source_instance or Koha::Schema::Result::AqbudgetsPlanning::result_source_instance or Koha::Schema::Result::Aqcontact::result_source_instance or Koha::Schema::Result::Aqcontract::result_source_instance or Koha::Schema::Result::Aqinvoice::result_source_instance or Koha::Schema::Result::Aqorder::result_source_instance or Koha::Schema::Result::AqorderUser::result_source_instance or Koha::Schema::Result::AqordersItem::result_source_instance or Koha::Schema::Result::AqordersTransfer::result_source_instance or Koha::Schema::Result::AudioAlert::result_source_instance or Koha::Schema::Result::AuthHeader::result_source_instance or Koha::Schema::Result::AuthSubfieldStructure::result_source_instance or Koha::Schema::Result::AuthTagStructure::result_source_instance or Koha::Schema::Result::AuthType::result_source_instance or Koha::Schema::Result::AuthorisedValue::result_source_instance or Koha::Schema::Result::AuthorisedValuesBranch::result_source_instance or Koha::Schema::Result::Biblio::result_source_instance or Koha::Schema::Result::BiblioFramework::result_source_instance or Koha::Schema::Result::Biblioimage::result_source_instance or Koha::Schema::Result::Biblioitem::result_source_instance or Koha::Schema::Result::Borrower::result_source_instance or Koha::Schema::Result::BorrowerAttribute::result_source_instance or Koha::Schema::Result::BorrowerAttributeType::result_source_instance or Koha::Schema::Result::BorrowerAttributeTypesBranch::result_source_instance or Koha::Schema::Result::BorrowerDebarment::result_source_instance or Koha::Schema::Result::BorrowerFile::result_source_instance or Koha::Schema::Result::BorrowerMessagePreference::result_source_instance or Koha::Schema::Result::BorrowerMessageTransportPreference::result_source_instance or Koha::Schema::Result::BorrowerModification::result_source_instance or Koha::Schema::Result::BorrowerSync::result_source_instance or Koha::Schema::Result::Branch::result_source_instance or Koha::Schema::Result::BranchBorrowerCircRule::result_source_instance or Koha::Schema::Result::BranchItemRule::result_source_instance or Koha::Schema::Result::BranchTransferLimit::result_source_instance or Koha::Schema::Result::Branchcategory::result_source_instance or Koha::Schema::Result::Branchrelation::result_source_instance or Koha::Schema::Result::Branchtransfer::result_source_instance or Koha::Schema::Result::Browser::result_source_instance or Koha::Schema::Result::CategoriesBranch::result_source_instance or Koha::Schema::Result::Category::result_source_instance or Koha::Schema::Result::City::result_source_instance or Koha::Schema::Result::ClassSortRule::result_source_instance or Koha::Schema::Result::ClassSource::result_source_instance or Koha::Schema::Result::Collection::result_source_instance or Koha::Schema::Result::CollectionsTracking::result_source_instance or Koha::Schema::Result::ColumnsSetting::result_source_instance or Koha::Schema::Result::Course::result_source_instance or Koha::Schema::Result::CourseInstructor::result_source_instance or Koha::Schema::Result::CourseItem::result_source_instance or Koha::Schema::Result::CourseReserve::result_source_instance or Koha::Schema::Result::CreatorBatch::result_source_instance or Koha::Schema::Result::CreatorImage::result_source_instance or Koha::Schema::Result::CreatorLayout::result_source_instance or Koha::Schema::Result::CreatorTemplate::result_source_instance or Koha::Schema::Result::Currency::result_source_instance or Koha::Schema::Result::DefaultBorrowerCircRule::result_source_instance or Koha::Schema::Result::DefaultBranchCircRule::result_source_instance or Koha::Schema::Result::DefaultBranchItemRule::result_source_instance or Koha::Schema::Result::DefaultCircRule::result_source_instance or Koha::Schema::Result::Deletedbiblio::result_source_instance or Koha::Schema::Result::Deletedbiblioitem::result_source_instance or Koha::Schema::Result::Deletedborrower::result_source_instance or Koha::Schema::Result::Deleteditem::result_source_instance or Koha::Schema::Result::Discharge::result_source_instance or Koha::Schema::Result::ExportFormat::result_source_instance or Koha::Schema::Result::Fieldmapping::result_source_instance or Koha::Schema::Result::HoldFillTarget::result_source_instance or Koha::Schema::Result::ImportAuth::result_source_instance or Koha::Schema::Result::ImportBatch::result_source_instance or Koha::Schema::Result::ImportBiblio::result_source_instance or Koha::Schema::Result::ImportItem::result_source_instance or Koha::Schema::Result::ImportRecord::result_source_instance or Koha::Schema::Result::ImportRecordMatch::result_source_instance or Koha::Schema::Result::Issue::result_source_instance or Koha::Schema::Result::Issuingrule::result_source_instance or Koha::Schema::Result::Item::result_source_instance or Koha::Schema::Result::ItemCirculationAlertPreference::result_source_instance or Koha::Schema::Result::ItemsLastBorrower::result_source_instance or Koha::Schema::Result::ItemsSearchField::result_source_instance or Koha::Schema::Result::Itemtype::result_source_instance or Koha::Schema::Result::LanguageDescription::result_source_instance or Koha::Schema::Result::LanguageRfc4646ToIso639::result_source_instance or Koha::Schema::Result::LanguageScriptBidi::result_source_instance or Koha::Schema::Result::LanguageScriptMapping::result_source_instance or Koha::Schema::Result::LanguageSubtagRegistry::result_source_instance or Koha::Schema::Result::Letter::result_source_instance or Koha::Schema::Result::Linktracker::result_source_instance or Koha::Schema::Result::Localization::result_source_instance or Koha::Schema::Result::MarcMatcher::result_source_instance or Koha::Schema::Result::MarcModificationTemplate::result_source_instance or Koha::Schema::Result::MarcModificationTemplateAction::result_source_instance or Koha::Schema::Result::MarcSubfieldStructure::result_source_instance or Koha::Schema::Result::MarcTagStructure::result_source_instance or Koha::Schema::Result::Matchcheck::result_source_instance or Koha::Schema::Result::MatcherMatchpoint::result_source_instance or Koha::Schema::Result::Matchpoint::result_source_instance or Koha::Schema::Result::MatchpointComponent::result_source_instance or Koha::Schema::Result::MatchpointComponentNorm::result_source_instance or Koha::Schema::Result::Message::result_source_instance or Koha::Schema::Result::MessageAttribute::result_source_instance or Koha::Schema::Result::MessageQueue::result_source_instance or Koha::Schema::Result::MessageTransport::result_source_instance or Koha::Schema::Result::MessageTransportType::result_source_instance or Koha::Schema::Result::MiscFile::result_source_instance or Koha::Schema::Result::NeedMergeAuthority::result_source_instance or Koha::Schema::Result::Notify::result_source_instance or Koha::Schema::Result::OaiSet::result_source_instance or Koha::Schema::Result::OaiSetsBiblio::result_source_instance or Koha::Schema::Result::OaiSetsDescription::result_source_instance or Koha::Schema::Result::OaiSetsMapping::result_source_instance or Koha::Schema::Result::OldIssue::result_source_instance or Koha::Schema::Result::OldReserve::result_source_instance or Koha::Schema::Result::OpacNews::result_source_instance or Koha::Schema::Result::Overduerule::result_source_instance or Koha::Schema::Result::OverduerulesTransportType::result_source_instance or Koha::Schema::Result::PatronList::result_source_instance or Koha::Schema::Result::PatronListPatron::result_source_instance or Koha::Schema::Result::Patronimage::result_source_instance or Koha::Schema::Result::PendingOfflineOperation::result_source_instance or Koha::Schema::Result::Permission::result_source_instance or Koha::Schema::Result::PluginData::result_source_instance or Koha::Schema::Result::Printer::result_source_instance or Koha::Schema::Result::PrintersProfile::result_source_instance or Koha::Schema::Result::Quote::result_source_instance or Koha::Schema::Result::Rating::result_source_instance or Koha::Schema::Result::RepeatableHoliday::result_source_instance or Koha::Schema::Result::ReportsDictionary::result_source_instance or Koha::Schema::Result::Reserve::result_source_instance or Koha::Schema::Result::Review::result_source_instance or Koha::Schema::Result::SavedReport::result_source_instance or Koha::Schema::Result::SavedSql::result_source_instance or Koha::Schema::Result::SearchHistory::result_source_instance or Koha::Schema::Result::Serial::result_source_instance or Koha::Schema::Result::Serialitem::result_source_instance or Koha::Schema::Result::ServicesThrottle::result_source_instance or Koha::Schema::Result::Session::result_source_instance or Koha::Schema::Result::SocialData::result_source_instance or Koha::Schema::Result::SpecialHoliday::result_source_instance or Koha::Schema::Result::Statistic::result_source_instance or Koha::Schema::Result::Stopword::result_source_instance or Koha::Schema::Result::Subscription::result_source_instance or Koha::Schema::Result::SubscriptionFrequency::result_source_instance or Koha::Schema::Result::SubscriptionNumberpattern::result_source_instance or Koha::Schema::Result::Subscriptionhistory::result_source_instance or Koha::Schema::Result::Subscriptionroutinglist::result_source_instance or Koha::Schema::Result::Suggestion::result_source_instance or Koha::Schema::Result::Systempreference::result_source_instance or Koha::Schema::Result::Tag::result_source_instance or Koha::Schema::Result::TagAll::result_source_instance or Koha::Schema::Result::TagsApproval::result_source_instance or Koha::Schema::Result::TagsIndex::result_source_instance or Koha::Schema::Result::TmpHoldsqueue::result_source_instance or Koha::Schema::Result::TransportCost::result_source_instance or Koha::Schema::Result::UploadedFile::result_source_instance or Koha::Schema::Result::UserPermission::result_source_instance or Koha::Schema::Result::Userflag::result_source_instance or Koha::Schema::Result::Virtualshelfcontent::result_source_instance or Koha::Schema::Result::Virtualshelfshare::result_source_instance or Koha::Schema::Result::Virtualshelve::result_source_instance or Koha::Schema::Result::Z3950server::result_source_instance or Koha::Schema::Result::Zebraqueue::result_source_instance at line 2 of (eval 167)[Class/Accessor/Grouped.pm:764], avg 14µs/call
# 6349 times (39.2ms+3.71ms) by DBIx::Class::AccessorGroup::get_component_class at line 13 of DBIx/Class/AccessorGroup.pm, avg 7µs/call | ||||
| 363 | 21437 | 11.9ms | if ( length (ref ($_[0]) ) ) { | ||
| 364 | 18527 | 87.0ms | 18527 | 16.4ms | if (Scalar::Util::reftype $_[0] eq 'HASH') { # spent 16.4ms making 18527 calls to Scalar::Util::reftype, avg 885ns/call |
| 365 | 18527 | 88.5ms | return $_[0]->{$_[1]} if exists $_[0]->{$_[1]}; | ||
| 366 | # everything in @_ is aliased, an assignment won't work | ||||
| 367 | 3004 | 6.94ms | splice @_, 0, 1, ref($_[0]); | ||
| 368 | } | ||||
| 369 | else { | ||||
| 370 | Carp::croak('Cannot get inherited value on an object instance that is not hash-based'); | ||||
| 371 | } | ||||
| 372 | } | ||||
| 373 | |||||
| 374 | # if we got this far there is nothing in the instance | ||||
| 375 | # OR this is a class call | ||||
| 376 | # in any case $_[0] contains the class name (see splice above) | ||||
| 377 | 2 | 43µs | 2 | 21µs | # spent 15µs (9+6) within Class::Accessor::Grouped::BEGIN@377 which was called:
# once (9µs+6µs) by base::import at line 377 # spent 15µs making 1 call to Class::Accessor::Grouped::BEGIN@377
# spent 6µs making 1 call to strict::unimport |
| 378 | 2 | 216µs | 2 | 36µs | # spent 24µs (11+13) within Class::Accessor::Grouped::BEGIN@378 which was called:
# once (11µs+13µs) by base::import at line 378 # spent 24µs making 1 call to Class::Accessor::Grouped::BEGIN@378
# spent 13µs making 1 call to warnings::unimport |
| 379 | |||||
| 380 | 5914 | 4.47ms | my $cag_slot = '::__cag_'. $_[1]; | ||
| 381 | 5914 | 29.0ms | return ${$_[0].$cag_slot} if defined(${$_[0].$cag_slot}); | ||
| 382 | |||||
| 383 | do { return ${$_.$cag_slot} if defined(${$_.$cag_slot}) } | ||||
| 384 | 3179 | 45.3ms | 3179 | 37.9ms | for $_[0]->get_super_paths; # spent 37.9ms making 3179 calls to Class::Accessor::Grouped::get_super_paths, avg 12µs/call |
| 385 | |||||
| 386 | 1 | 4µs | return undef; | ||
| 387 | } | ||||
| 388 | |||||
| 389 | =head2 set_inherited | ||||
| 390 | |||||
| 391 | =over 4 | ||||
| 392 | |||||
| 393 | =item Arguments: $field, $new_value | ||||
| 394 | |||||
| 395 | Returns: $new_value | ||||
| 396 | |||||
| 397 | =back | ||||
| 398 | |||||
| 399 | Simple setter for Classes and hash-based objects which sets and then returns | ||||
| 400 | the value for the field name passed as an argument. When called on a hash-based | ||||
| 401 | object it will set the appropriate hash key value. When called on a class, it | ||||
| 402 | will set a class level variable. | ||||
| 403 | |||||
| 404 | B<Note:>: This method will die if you try to set an object variable on a non | ||||
| 405 | hash-based object. | ||||
| 406 | |||||
| 407 | =cut | ||||
| 408 | |||||
| 409 | # spent 2.53ms (2.41+114µs) within Class::Accessor::Grouped::set_inherited which was called 720 times, avg 4µs/call:
# 706 times (2.31ms+114µs) by DBIx::Class::Schema::class_mappings or DBIx::Class::Schema::source_registrations or DBIx::Class::Schema::storage or DBIx::Class::Storage::DBI::sql_limit_dialect or DBIx::Class::Storage::DBI::sql_name_sep or DBIx::Class::Storage::DBI::sql_quote_char or DBIx::Class::_skip_namespace_frames or Koha::Schema::Result::Accountline::result_source_instance or Koha::Schema::Result::Accountoffset::result_source_instance or Koha::Schema::Result::ActionLog::result_source_instance or Koha::Schema::Result::ActionLogs::result_source_instance or Koha::Schema::Result::AdditionalField::result_source_instance or Koha::Schema::Result::AdditionalFieldValue::result_source_instance or Koha::Schema::Result::Alert::result_source_instance or Koha::Schema::Result::Aqbasket::result_source_instance or Koha::Schema::Result::Aqbasketgroup::result_source_instance or Koha::Schema::Result::Aqbasketuser::result_source_instance or Koha::Schema::Result::Aqbookseller::result_source_instance or Koha::Schema::Result::Aqbudget::result_source_instance or Koha::Schema::Result::Aqbudgetborrower::result_source_instance or Koha::Schema::Result::Aqbudgetperiod::result_source_instance or Koha::Schema::Result::AqbudgetsPlanning::result_source_instance or Koha::Schema::Result::Aqcontact::result_source_instance or Koha::Schema::Result::Aqcontract::result_source_instance or Koha::Schema::Result::Aqinvoice::result_source_instance or Koha::Schema::Result::Aqorder::result_source_instance or Koha::Schema::Result::AqorderUser::result_source_instance or Koha::Schema::Result::AqordersItem::result_source_instance or Koha::Schema::Result::AqordersTransfer::result_source_instance or Koha::Schema::Result::AudioAlert::result_source_instance or Koha::Schema::Result::AuthHeader::result_source_instance or Koha::Schema::Result::AuthSubfieldStructure::result_source_instance or Koha::Schema::Result::AuthTagStructure::result_source_instance or Koha::Schema::Result::AuthType::result_source_instance or Koha::Schema::Result::AuthorisedValue::result_source_instance or Koha::Schema::Result::AuthorisedValuesBranch::result_source_instance or Koha::Schema::Result::Biblio::result_source_instance or Koha::Schema::Result::BiblioFramework::result_source_instance or Koha::Schema::Result::Biblioimage::result_source_instance or Koha::Schema::Result::Biblioitem::result_source_instance or Koha::Schema::Result::Borrower::result_source_instance or Koha::Schema::Result::BorrowerAttribute::result_source_instance or Koha::Schema::Result::BorrowerAttributeType::result_source_instance or Koha::Schema::Result::BorrowerAttributeTypesBranch::result_source_instance or Koha::Schema::Result::BorrowerDebarment::result_source_instance or Koha::Schema::Result::BorrowerFile::result_source_instance or Koha::Schema::Result::BorrowerMessagePreference::result_source_instance or Koha::Schema::Result::BorrowerMessageTransportPreference::result_source_instance or Koha::Schema::Result::BorrowerModification::result_source_instance or Koha::Schema::Result::BorrowerSync::result_source_instance or Koha::Schema::Result::Branch::result_source_instance or Koha::Schema::Result::BranchBorrowerCircRule::result_source_instance or Koha::Schema::Result::BranchItemRule::result_source_instance or Koha::Schema::Result::BranchTransferLimit::result_source_instance or Koha::Schema::Result::Branchcategory::result_source_instance or Koha::Schema::Result::Branchrelation::result_source_instance or Koha::Schema::Result::Branchtransfer::result_source_instance or Koha::Schema::Result::Browser::result_source_instance or Koha::Schema::Result::CategoriesBranch::result_source_instance or Koha::Schema::Result::Category::result_source_instance or Koha::Schema::Result::City::result_source_instance or Koha::Schema::Result::ClassSortRule::result_source_instance or Koha::Schema::Result::ClassSource::result_source_instance or Koha::Schema::Result::Collection::result_source_instance or Koha::Schema::Result::CollectionsTracking::result_source_instance or Koha::Schema::Result::ColumnsSetting::result_source_instance or Koha::Schema::Result::Course::result_source_instance or Koha::Schema::Result::CourseInstructor::result_source_instance or Koha::Schema::Result::CourseItem::result_source_instance or Koha::Schema::Result::CourseReserve::result_source_instance or Koha::Schema::Result::CreatorBatch::result_source_instance or Koha::Schema::Result::CreatorImage::result_source_instance or Koha::Schema::Result::CreatorLayout::result_source_instance or Koha::Schema::Result::CreatorTemplate::result_source_instance or Koha::Schema::Result::Currency::result_source_instance or Koha::Schema::Result::DefaultBorrowerCircRule::result_source_instance or Koha::Schema::Result::DefaultBranchCircRule::result_source_instance or Koha::Schema::Result::DefaultBranchItemRule::result_source_instance or Koha::Schema::Result::DefaultCircRule::result_source_instance or Koha::Schema::Result::Deletedbiblio::result_source_instance or Koha::Schema::Result::Deletedbiblioitem::result_source_instance or Koha::Schema::Result::Deletedborrower::result_source_instance or Koha::Schema::Result::Deleteditem::result_source_instance or Koha::Schema::Result::Discharge::result_source_instance or Koha::Schema::Result::ExportFormat::result_source_instance or Koha::Schema::Result::Fieldmapping::result_source_instance or Koha::Schema::Result::HoldFillTarget::result_source_instance or Koha::Schema::Result::ImportAuth::result_source_instance or Koha::Schema::Result::ImportBatch::result_source_instance or Koha::Schema::Result::ImportBiblio::result_source_instance or Koha::Schema::Result::ImportItem::result_source_instance or Koha::Schema::Result::ImportRecord::result_source_instance or Koha::Schema::Result::ImportRecordMatch::result_source_instance or Koha::Schema::Result::Issue::result_source_instance or Koha::Schema::Result::Issuingrule::result_source_instance or Koha::Schema::Result::Item::result_source_instance or Koha::Schema::Result::ItemCirculationAlertPreference::result_source_instance or Koha::Schema::Result::ItemsLastBorrower::result_source_instance or Koha::Schema::Result::ItemsSearchField::result_source_instance or Koha::Schema::Result::Itemtype::result_source_instance or Koha::Schema::Result::LanguageDescription::result_source_instance or Koha::Schema::Result::LanguageRfc4646ToIso639::result_source_instance or Koha::Schema::Result::LanguageScriptBidi::result_source_instance or Koha::Schema::Result::LanguageScriptMapping::result_source_instance or Koha::Schema::Result::LanguageSubtagRegistry::result_source_instance or Koha::Schema::Result::Letter::result_source_instance or Koha::Schema::Result::Linktracker::result_source_instance or Koha::Schema::Result::Localization::result_source_instance or Koha::Schema::Result::MarcMatcher::result_source_instance or Koha::Schema::Result::MarcModificationTemplate::result_source_instance or Koha::Schema::Result::MarcModificationTemplateAction::result_source_instance or Koha::Schema::Result::MarcSubfieldStructure::result_source_instance or Koha::Schema::Result::MarcTagStructure::result_source_instance or Koha::Schema::Result::Matchcheck::result_source_instance or Koha::Schema::Result::MatcherMatchpoint::result_source_instance or Koha::Schema::Result::Matchpoint::result_source_instance or Koha::Schema::Result::MatchpointComponent::result_source_instance or Koha::Schema::Result::MatchpointComponentNorm::result_source_instance or Koha::Schema::Result::Message::result_source_instance or Koha::Schema::Result::MessageAttribute::result_source_instance or Koha::Schema::Result::MessageQueue::result_source_instance or Koha::Schema::Result::MessageTransport::result_source_instance or Koha::Schema::Result::MessageTransportType::result_source_instance or Koha::Schema::Result::MiscFile::result_source_instance or Koha::Schema::Result::NeedMergeAuthority::result_source_instance or Koha::Schema::Result::Notify::result_source_instance or Koha::Schema::Result::OaiSet::result_source_instance or Koha::Schema::Result::OaiSetsBiblio::result_source_instance or Koha::Schema::Result::OaiSetsDescription::result_source_instance or Koha::Schema::Result::OaiSetsMapping::result_source_instance or Koha::Schema::Result::OldIssue::result_source_instance or Koha::Schema::Result::OldReserve::result_source_instance or Koha::Schema::Result::OpacNews::result_source_instance or Koha::Schema::Result::Overduerule::result_source_instance or Koha::Schema::Result::OverduerulesTransportType::result_source_instance or Koha::Schema::Result::PatronList::result_source_instance or Koha::Schema::Result::PatronListPatron::result_source_instance or Koha::Schema::Result::Patronimage::result_source_instance or Koha::Schema::Result::PendingOfflineOperation::result_source_instance or Koha::Schema::Result::Permission::result_source_instance or Koha::Schema::Result::PluginData::result_source_instance or Koha::Schema::Result::Printer::result_source_instance or Koha::Schema::Result::PrintersProfile::result_source_instance or Koha::Schema::Result::Quote::result_source_instance or Koha::Schema::Result::Rating::result_source_instance or Koha::Schema::Result::RepeatableHoliday::result_source_instance or Koha::Schema::Result::ReportsDictionary::result_source_instance or Koha::Schema::Result::Reserve::result_source_instance or Koha::Schema::Result::Review::result_source_instance or Koha::Schema::Result::SavedReport::result_source_instance or Koha::Schema::Result::SavedSql::result_source_instance or Koha::Schema::Result::SearchHistory::result_source_instance or Koha::Schema::Result::Serial::result_source_instance or Koha::Schema::Result::Serialitem::result_source_instance or Koha::Schema::Result::ServicesThrottle::result_source_instance or Koha::Schema::Result::Session::result_source_instance or Koha::Schema::Result::SocialData::result_source_instance or Koha::Schema::Result::SpecialHoliday::result_source_instance or Koha::Schema::Result::Statistic::result_source_instance or Koha::Schema::Result::Stopword::result_source_instance or Koha::Schema::Result::Subscription::result_source_instance or Koha::Schema::Result::SubscriptionFrequency::result_source_instance or Koha::Schema::Result::SubscriptionNumberpattern::result_source_instance or Koha::Schema::Result::Subscriptionhistory::result_source_instance or Koha::Schema::Result::Subscriptionroutinglist::result_source_instance or Koha::Schema::Result::Suggestion::result_source_instance or Koha::Schema::Result::Systempreference::result_source_instance or Koha::Schema::Result::Tag::result_source_instance or Koha::Schema::Result::TagAll::result_source_instance or Koha::Schema::Result::TagsApproval::result_source_instance or Koha::Schema::Result::TagsIndex::result_source_instance or Koha::Schema::Result::TmpHoldsqueue::result_source_instance or Koha::Schema::Result::TransportCost::result_source_instance or Koha::Schema::Result::UploadedFile::result_source_instance or Koha::Schema::Result::UserPermission::result_source_instance or Koha::Schema::Result::Userflag::result_source_instance or Koha::Schema::Result::Virtualshelfcontent::result_source_instance or Koha::Schema::Result::Virtualshelfshare::result_source_instance or Koha::Schema::Result::Virtualshelve::result_source_instance or Koha::Schema::Result::Z3950server::result_source_instance or Koha::Schema::Result::Zebraqueue::result_source_instance at line 2 of (eval 167)[Class/Accessor/Grouped.pm:764], avg 3µs/call
# 7 times (25µs+0s) by DBIx::Class::mk_classaccessor at line 37 of DBIx/Class.pm, avg 4µs/call
# 5 times (75µs+0s) by DBIx::Class::AccessorGroup::set_component_class at line 32 of DBIx/Class/AccessorGroup.pm, avg 15µs/call
# 2 times (8µs+0s) by DBIx::Class::Storage::DBI::set_use_dbms_capability at line 1072 of DBIx/Class/Storage/DBI.pm, avg 4µs/call | ||||
| 410 | 720 | 1.23ms | 180 | 114µs | if (length (ref ($_[0]) ) ) { # spent 114µs making 180 calls to Scalar::Util::reftype, avg 635ns/call |
| 411 | if (Scalar::Util::reftype $_[0] eq 'HASH') { | ||||
| 412 | return $_[0]->{$_[1]} = $_[2]; | ||||
| 413 | } else { | ||||
| 414 | Carp::croak('Cannot set inherited value on an object instance that is not hash-based'); | ||||
| 415 | }; | ||||
| 416 | } | ||||
| 417 | |||||
| 418 | 2 | 1.10ms | 2 | 20µs | # spent 15µs (9+6) within Class::Accessor::Grouped::BEGIN@418 which was called:
# once (9µs+6µs) by base::import at line 418 # spent 15µs making 1 call to Class::Accessor::Grouped::BEGIN@418
# spent 6µs making 1 call to strict::unimport |
| 419 | 540 | 2.63ms | ${$_[0].'::__cag_'.$_[1]} = $_[2]; | ||
| 420 | } | ||||
| 421 | |||||
| 422 | =head2 get_component_class | ||||
| 423 | |||||
| 424 | =over 4 | ||||
| 425 | |||||
| 426 | =item Arguments: $field | ||||
| 427 | |||||
| 428 | Returns: $value | ||||
| 429 | |||||
| 430 | =back | ||||
| 431 | |||||
| 432 | Gets the value of the specified component class. | ||||
| 433 | |||||
| 434 | __PACKAGE__->mk_group_accessors('component_class' => 'result_class'); | ||||
| 435 | |||||
| 436 | $self->result_class->method(); | ||||
| 437 | |||||
| 438 | ## same as | ||||
| 439 | $self->get_component_class('result_class')->method(); | ||||
| 440 | |||||
| 441 | =cut | ||||
| 442 | |||||
| 443 | sub get_component_class { | ||||
| 444 | $_[0]->get_inherited($_[1]); | ||||
| 445 | }; | ||||
| 446 | |||||
| 447 | =head2 set_component_class | ||||
| 448 | |||||
| 449 | =over 4 | ||||
| 450 | |||||
| 451 | =item Arguments: $field, $class | ||||
| 452 | |||||
| 453 | Returns: $new_value | ||||
| 454 | |||||
| 455 | =back | ||||
| 456 | |||||
| 457 | Inherited accessor that automatically loads the specified class before setting | ||||
| 458 | it. This method will die if the specified class could not be loaded. | ||||
| 459 | |||||
| 460 | __PACKAGE__->mk_group_accessors('component_class' => 'result_class'); | ||||
| 461 | __PACKAGE__->result_class('MyClass'); | ||||
| 462 | |||||
| 463 | $self->result_class->method(); | ||||
| 464 | |||||
| 465 | =cut | ||||
| 466 | |||||
| 467 | sub set_component_class { | ||||
| 468 | if (defined $_[2] and length $_[2]) { | ||||
| 469 | # disable warnings, and prevent $_ being eaten away by a behind-the-scenes | ||||
| 470 | # module loading | ||||
| 471 | local ($^W, $_); | ||||
| 472 | |||||
| 473 | if (__CAG_ENV__::UNSTABLE_DOLLARAT) { | ||||
| 474 | my $err; | ||||
| 475 | { | ||||
| 476 | local $@; | ||||
| 477 | eval { Module::Runtime::use_package_optimistically($_[2]) } | ||||
| 478 | or $err = $@; | ||||
| 479 | } | ||||
| 480 | Carp::croak("Could not load $_[1] '$_[2]': $err") if defined $err; | ||||
| 481 | |||||
| 482 | } | ||||
| 483 | else { | ||||
| 484 | eval { Module::Runtime::use_package_optimistically($_[2]) } | ||||
| 485 | or Carp::croak("Could not load $_[1] '$_[2]': $@"); | ||||
| 486 | } | ||||
| 487 | }; | ||||
| 488 | |||||
| 489 | $_[0]->set_inherited($_[1], $_[2]); | ||||
| 490 | }; | ||||
| 491 | |||||
| 492 | =head1 INTERNAL METHODS | ||||
| 493 | |||||
| 494 | These methods are documented for clarity, but are never meant to be called | ||||
| 495 | directly, and are not really meant for overriding either. | ||||
| 496 | |||||
| 497 | =head2 get_super_paths | ||||
| 498 | |||||
| 499 | Returns a list of 'parent' or 'super' class names that the current class | ||||
| 500 | inherited from. This is what drives the traversal done by L</get_inherited>. | ||||
| 501 | |||||
| 502 | =cut | ||||
| 503 | |||||
| 504 | # spent 37.9ms (27.6+10.3) within Class::Accessor::Grouped::get_super_paths which was called 3179 times, avg 12µs/call:
# 3179 times (27.6ms+10.3ms) by Class::Accessor::Grouped::get_inherited at line 384, avg 12µs/call | ||||
| 505 | # get_linear_isa returns the class itself as the 1st element | ||||
| 506 | # use @_ as a pre-allocated scratch array | ||||
| 507 | 3179 | 31.2ms | 3179 | 10.3ms | (undef, @_) = @{mro::get_linear_isa( length( ref($_[0]) ) ? ref($_[0]) : $_[0] )}; # spent 10.3ms making 3179 calls to mro::get_linear_isa, avg 3µs/call |
| 508 | 3179 | 30.7ms | @_; | ||
| 509 | }; | ||||
| 510 | |||||
| 511 | =head2 make_group_accessor | ||||
| 512 | |||||
| 513 | __PACKAGE__->make_group_accessor('simple', 'hair_length', 'hair_length'); | ||||
| 514 | __PACKAGE__->make_group_accessor('simple', 'hc', 'hair_color'); | ||||
| 515 | |||||
| 516 | =over 4 | ||||
| 517 | |||||
| 518 | =item Arguments: $group, $field, $accessor | ||||
| 519 | |||||
| 520 | Returns: \&accessor_coderef ? | ||||
| 521 | |||||
| 522 | =back | ||||
| 523 | |||||
| 524 | Called by mk_group_accessors for each entry in @fieldspec. Either returns | ||||
| 525 | a coderef which will be installed at C<&__PACKAGE__::$accessor>, or returns | ||||
| 526 | C<undef> if it elects to install the coderef on its own. | ||||
| 527 | |||||
| 528 | =cut | ||||
| 529 | |||||
| 530 | 3938 | 9.15ms | 3938 | 490ms | # spent 517ms (27.2+490) within Class::Accessor::Grouped::make_group_accessor which was called 3938 times, avg 131µs/call:
# 3938 times (27.2ms+490ms) by Class::Accessor::Grouped::_mk_group_accessors at line 146, avg 131µs/call # spent 490ms making 3938 calls to Class::Accessor::Grouped::__ANON__[Class/Accessor/Grouped.pm:942], avg 124µs/call |
| 531 | |||||
| 532 | =head2 make_group_ro_accessor | ||||
| 533 | |||||
| 534 | __PACKAGE__->make_group_ro_accessor('simple', 'birthdate', 'birthdate'); | ||||
| 535 | __PACKAGE__->make_group_ro_accessor('simple', 'ssn', 'social_security_number'); | ||||
| 536 | |||||
| 537 | =over 4 | ||||
| 538 | |||||
| 539 | =item Arguments: $group, $field, $accessor | ||||
| 540 | |||||
| 541 | Returns: \&accessor_coderef ? | ||||
| 542 | |||||
| 543 | =back | ||||
| 544 | |||||
| 545 | Called by mk_group_ro_accessors for each entry in @fieldspec. Either returns | ||||
| 546 | a coderef which will be installed at C<&__PACKAGE__::$accessor>, or returns | ||||
| 547 | C<undef> if it elects to install the coderef on its own. | ||||
| 548 | |||||
| 549 | =cut | ||||
| 550 | |||||
| 551 | sub make_group_ro_accessor { $gen_accessor->('ro', @_) } | ||||
| 552 | |||||
| 553 | =head2 make_group_wo_accessor | ||||
| 554 | |||||
| 555 | __PACKAGE__->make_group_wo_accessor('simple', 'lie', 'lie'); | ||||
| 556 | __PACKAGE__->make_group_wo_accessor('simple', 'subj', 'subject'); | ||||
| 557 | |||||
| 558 | =over 4 | ||||
| 559 | |||||
| 560 | =item Arguments: $group, $field, $accessor | ||||
| 561 | |||||
| 562 | Returns: \&accessor_coderef ? | ||||
| 563 | |||||
| 564 | =back | ||||
| 565 | |||||
| 566 | Called by mk_group_wo_accessors for each entry in @fieldspec. Either returns | ||||
| 567 | a coderef which will be installed at C<&__PACKAGE__::$accessor>, or returns | ||||
| 568 | C<undef> if it elects to install the coderef on its own. | ||||
| 569 | |||||
| 570 | =cut | ||||
| 571 | |||||
| 572 | sub make_group_wo_accessor { $gen_accessor->('wo', @_) } | ||||
| 573 | |||||
| 574 | |||||
| 575 | =head1 PERFORMANCE | ||||
| 576 | |||||
| 577 | To provide total flexibility L<Class::Accessor::Grouped> calls methods | ||||
| 578 | internally while performing get/set actions, which makes it noticeably | ||||
| 579 | slower than similar modules. To compensate, this module will automatically | ||||
| 580 | use the insanely fast L<Class::XSAccessor> to generate the C<simple>-group | ||||
| 581 | accessors if this module is available on your system. | ||||
| 582 | |||||
| 583 | =head2 Benchmark | ||||
| 584 | |||||
| 585 | This is the benchmark of 200 get/get/set/get/set cycles on perl 5.16.2 with | ||||
| 586 | thread support, showcasing how this modules L<simple (CAG_S)|/get_simple>, | ||||
| 587 | L<inherited (CAG_INH)|/get_inherited> and L<inherited with parent-class data | ||||
| 588 | (CAG_INHP)|/get_inherited> accessors stack up against most popular accessor | ||||
| 589 | builders: L<Moose>, L<Moo>, L<Mo>, L<Mouse> (both pure-perl and XS variant), | ||||
| 590 | L<Object::Tiny::RW (OTRW)|Object::Tiny::RW>, | ||||
| 591 | L<Class::Accessor (CA)|Class::Accessor>, | ||||
| 592 | L<Class::Accessor::Lite (CAL)|Class::Accessor::Lite>, | ||||
| 593 | L<Class::Accessor::Fast (CAF)|Class::Accessor::Fast>, | ||||
| 594 | L<Class::Accessor::Fast::XS (CAF_XS)|Class::Accessor::Fast::XS> | ||||
| 595 | and L<Class::XSAccessor (XSA)|Class::XSAccessor> | ||||
| 596 | |||||
| 597 | Rate CAG_INHP CAG_INH CA CAG_S CAF moOse OTRW CAL mo moUse HANDMADE moo CAF_XS moUse_XS XSA | ||||
| 598 | |||||
| 599 | CAG_INHP 287.021+-0.02/s -- -0.3% -10.0% -37.1% -53.1% -53.6% -53.7% -54.1% -56.9% -59.0% -59.6% -59.8% -78.7% -81.9% -83.5% | ||||
| 600 | |||||
| 601 | CAG_INH 288.025+-0.031/s 0.3% -- -9.7% -36.9% -52.9% -53.5% -53.5% -53.9% -56.7% -58.8% -59.5% -59.7% -78.6% -81.9% -83.5% | ||||
| 602 | |||||
| 603 | CA 318.967+-0.047/s 11.1% 10.7% -- -30.1% -47.9% -48.5% -48.5% -49.0% -52.1% -54.4% -55.1% -55.3% -76.3% -79.9% -81.7% | ||||
| 604 | |||||
| 605 | CAG_S 456.107+-0.054/s 58.9% 58.4% 43.0% -- -25.4% -26.3% -26.4% -27.0% -31.5% -34.8% -35.8% -36.1% -66.1% -71.3% -73.9% | ||||
| 606 | |||||
| 607 | CAF 611.745+-0.099/s 113.1% 112.4% 91.8% 34.1% -- -1.2% -1.2% -2.1% -8.1% -12.6% -14.0% -14.3% -54.5% -61.5% -64.9% | ||||
| 608 | |||||
| 609 | moOse 619.051+-0.059/s 115.7% 114.9% 94.1% 35.7% 1.2% -- -0.1% -1.0% -7.0% -11.6% -12.9% -13.3% -54.0% -61.0% -64.5% | ||||
| 610 | |||||
| 611 | OTRW 619.475+-0.1/s 115.8% 115.1% 94.2% 35.8% 1.3% 0.1% -- -0.9% -6.9% -11.5% -12.9% -13.2% -54.0% -61.0% -64.5% | ||||
| 612 | |||||
| 613 | CAL 625.106+-0.085/s 117.8% 117.0% 96.0% 37.1% 2.2% 1.0% 0.9% -- -6.1% -10.7% -12.1% -12.5% -53.5% -60.6% -64.2% | ||||
| 614 | |||||
| 615 | mo 665.44+-0.12/s 131.8% 131.0% 108.6% 45.9% 8.8% 7.5% 7.4% 6.5% -- -4.9% -6.4% -6.8% -50.5% -58.1% -61.9% | ||||
| 616 | |||||
| 617 | moUse 699.9+-0.15/s 143.9% 143.0% 119.4% 53.5% 14.4% 13.1% 13.0% 12.0% 5.2% -- -1.6% -2.0% -48.0% -55.9% -59.9% | ||||
| 618 | |||||
| 619 | HANDMADE 710.98+-0.16/s 147.7% 146.8% 122.9% 55.9% 16.2% 14.9% 14.8% 13.7% 6.8% 1.6% -- -0.4% -47.2% -55.2% -59.2% | ||||
| 620 | |||||
| 621 | moo 714.04+-0.13/s 148.8% 147.9% 123.9% 56.6% 16.7% 15.3% 15.3% 14.2% 7.3% 2.0% 0.4% -- -46.9% -55.0% -59.1% | ||||
| 622 | |||||
| 623 | CAF_XS 1345.55+-0.051/s 368.8% 367.2% 321.8% 195.0% 120.0% 117.4% 117.2% 115.3% 102.2% 92.2% 89.3% 88.4% -- -15.3% -22.9% | ||||
| 624 | |||||
| 625 | moUse_XS 1588+-0.036/s 453.3% 451.3% 397.9% 248.2% 159.6% 156.5% 156.3% 154.0% 138.6% 126.9% 123.4% 122.4% 18.0% -- -9.0% | ||||
| 626 | |||||
| 627 | XSA 1744.67+-0.052/s 507.9% 505.7% 447.0% 282.5% 185.2% 181.8% 181.6% 179.1% 162.2% 149.3% 145.4% 144.3% 29.7% 9.9% -- | ||||
| 628 | |||||
| 629 | Benchmarking program is available in the root of the | ||||
| 630 | L<repository|http://search.cpan.org/dist/Class-Accessor-Grouped/>: | ||||
| 631 | |||||
| 632 | =head2 Notes on Class::XSAccessor | ||||
| 633 | |||||
| 634 | You can force (or disable) the use of L<Class::XSAccessor> before creating a | ||||
| 635 | particular C<simple> accessor by either manipulating the global variable | ||||
| 636 | C<$Class::Accessor::Grouped::USE_XS> to true or false (preferably with | ||||
| 637 | L<localization|perlfunc/local>, or you can do so before runtime via the | ||||
| 638 | C<CAG_USE_XS> environment variable. | ||||
| 639 | |||||
| 640 | Since L<Class::XSAccessor> has no knowledge of L</get_simple> and | ||||
| 641 | L</set_simple> this module does its best to detect if you are overriding | ||||
| 642 | one of these methods and will fall back to using the perl version of the | ||||
| 643 | accessor in order to maintain consistency. However be aware that if you | ||||
| 644 | enable use of C<Class::XSAccessor> (automatically or explicitly), create | ||||
| 645 | an object, invoke a simple accessor on that object, and B<then> manipulate | ||||
| 646 | the symbol table to install a C<get/set_simple> override - you get to keep | ||||
| 647 | all the pieces. | ||||
| 648 | |||||
| 649 | =head1 AUTHORS | ||||
| 650 | |||||
| 651 | Matt S. Trout <mst@shadowcatsystems.co.uk> | ||||
| 652 | |||||
| 653 | Christopher H. Laco <claco@chrislaco.com> | ||||
| 654 | |||||
| 655 | =head1 CONTRIBUTORS | ||||
| 656 | |||||
| 657 | Caelum: Rafael Kitover <rkitover@cpan.org> | ||||
| 658 | |||||
| 659 | frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com> | ||||
| 660 | |||||
| 661 | groditi: Guillermo Roditi <groditi@cpan.org> | ||||
| 662 | |||||
| 663 | Jason Plum <jason.plum@bmmsi.com> | ||||
| 664 | |||||
| 665 | ribasushi: Peter Rabbitson <ribasushi@cpan.org> | ||||
| 666 | |||||
| 667 | |||||
| 668 | =head1 COPYRIGHT & LICENSE | ||||
| 669 | |||||
| 670 | Copyright (c) 2006-2010 Matt S. Trout <mst@shadowcatsystems.co.uk> | ||||
| 671 | |||||
| 672 | This program is free software; you can redistribute it and/or modify | ||||
| 673 | it under the same terms as perl itself. | ||||
| 674 | |||||
| 675 | =cut | ||||
| 676 | |||||
| 677 | ######################################################################## | ||||
| 678 | ######################################################################## | ||||
| 679 | ######################################################################## | ||||
| 680 | # | ||||
| 681 | # Here be many angry dragons | ||||
| 682 | # (all code is in private coderefs since everything inherits CAG) | ||||
| 683 | # | ||||
| 684 | ######################################################################## | ||||
| 685 | ######################################################################## | ||||
| 686 | |||||
| 687 | # Autodetect unless flag supplied | ||||
| 688 | my $xsa_autodetected; | ||||
| 689 | 1 | 400ns | if (! defined $USE_XS) { | ||
| 690 | 1 | 100ns | $USE_XS = __CAG_ENV__::NO_CXSA ? 0 : 1; | ||
| 691 | 1 | 700ns | $xsa_autodetected++; | ||
| 692 | } | ||||
| 693 | |||||
| 694 | |||||
| 695 | my $maker_templates = { | ||||
| 696 | rw => { | ||||
| 697 | cxsa_call => 'accessors', | ||||
| 698 | # spent 8.87ms (6.40+2.47) within Class::Accessor::Grouped::__ANON__[/usr/share/perl5/Class/Accessor/Grouped.pm:708] which was called 927 times, avg 10µs/call:
# 927 times (6.40ms+2.47ms) by Class::Accessor::Grouped::__ANON__[/usr/share/perl5/Class/Accessor/Grouped.pm:942] at line 936, avg 10µs/call | ||||
| 699 | # my ($group, $fieldname) = @_; | ||||
| 700 | 927 | 2.27ms | 927 | 2.47ms | my $quoted_fieldname = __CAG_ENV__::perlstring($_[1]); # spent 2.47ms making 927 calls to __CAG_ENV__::perlstring, avg 3µs/call |
| 701 | 927 | 5.18ms | sprintf <<'EOS', ($_[0], $quoted_fieldname) x 2; | ||
| 702 | |||||
| 703 | @_ > 1 | ||||
| 704 | ? shift->set_%s(%s, @_) | ||||
| 705 | : shift->get_%s(%s) | ||||
| 706 | EOS | ||||
| 707 | |||||
| 708 | }, | ||||
| 709 | }, | ||||
| 710 | ro => { | ||||
| 711 | cxsa_call => 'getters', | ||||
| 712 | pp_generator => sub { | ||||
| 713 | # my ($group, $fieldname) = @_; | ||||
| 714 | my $quoted_fieldname = __CAG_ENV__::perlstring($_[1]); | ||||
| 715 | sprintf <<'EOS', $_[0], $quoted_fieldname; | ||||
| 716 | |||||
| 717 | @_ > 1 | ||||
| 718 | ? do { | ||||
| 719 | my ($meth) = (caller(0))[3] =~ /([^\:]+)$/; | ||||
| 720 | my $class = length( ref($_[0]) ) ? ref($_[0]) : $_[0]; | ||||
| 721 | Carp::croak( | ||||
| 722 | "'$meth' cannot alter its value (read-only attribute of class $class)" | ||||
| 723 | ); | ||||
| 724 | } | ||||
| 725 | : shift->get_%s(%s) | ||||
| 726 | EOS | ||||
| 727 | |||||
| 728 | }, | ||||
| 729 | }, | ||||
| 730 | wo => { | ||||
| 731 | cxsa_call => 'setters', | ||||
| 732 | pp_generator => sub { | ||||
| 733 | # my ($group, $fieldname) = @_; | ||||
| 734 | my $quoted_fieldname = __CAG_ENV__::perlstring($_[1]); | ||||
| 735 | sprintf <<'EOS', $_[0], $quoted_fieldname; | ||||
| 736 | |||||
| 737 | @_ > 1 | ||||
| 738 | ? shift->set_%s(%s, @_) | ||||
| 739 | : do { | ||||
| 740 | my ($meth) = (caller(0))[3] =~ /([^\:]+)$/; | ||||
| 741 | my $class = length( ref($_[0]) ) ? ref($_[0]) : $_[0]; | ||||
| 742 | Carp::croak( | ||||
| 743 | "'$meth' cannot access its value (write-only attribute of class $class)" | ||||
| 744 | ); | ||||
| 745 | } | ||||
| 746 | EOS | ||||
| 747 | |||||
| 748 | }, | ||||
| 749 | }, | ||||
| 750 | 1 | 13µs | }; | ||
| 751 | |||||
| 752 | # spent 420ms (370+50.7) within Class::Accessor::Grouped::__ANON__[/usr/share/perl5/Class/Accessor/Grouped.pm:774] which was called 927 times, avg 454µs/call:
# 927 times (370ms+50.7ms) by Class::Accessor::Grouped::__ANON__[/usr/share/perl5/Class/Accessor/Grouped.pm:942] at line 939, avg 454µs/call | ||||
| 753 | #my ($src, $no_warnings, $err_msg) = @_; | ||||
| 754 | |||||
| 755 | 927 | 1.19ms | my $src = sprintf "{ %s warnings; use strict; no strict 'refs'; %s }", | ||
| 756 | $_[1] ? 'no' : 'use', | ||||
| 757 | $_[0], | ||||
| 758 | ; | ||||
| 759 | |||||
| 760 | 927 | 123µs | my (@rv, $err); | ||
| 761 | { | ||||
| 762 | 927 | 243µs | local $@ if __CAG_ENV__::UNSTABLE_DOLLARAT; | ||
| 763 | wantarray | ||||
| 764 | 927 | 121ms | ? @rv = eval $src # spent 456ms executing statements in 927 string evals (merged) # includes 220ms spent executing 28783 calls to 6389 subs defined therein. | ||
| 765 | : $rv[0] = eval $src | ||||
| 766 | ; | ||||
| 767 | 927 | 513µs | $err = $@ if $@ ne ''; | ||
| 768 | } | ||||
| 769 | |||||
| 770 | 927 | 247µs | Carp::croak(join ': ', ($_[2] || 'String-eval failed'), "$err\n$src\n" ) | ||
| 771 | if defined $err; | ||||
| 772 | |||||
| 773 | 927 | 4.21ms | wantarray ? @rv : $rv[0]; | ||
| 774 | 1 | 2µs | }; | ||
| 775 | |||||
| 776 | 1 | 200ns | my ($accessor_maker_cache, $no_xsa_warned_classes); | ||
| 777 | |||||
| 778 | # can't use pkg_gen to track this stuff, as it doesn't | ||||
| 779 | # detect superclass mucking | ||||
| 780 | 1 | 15µs | 1 | 2µs | my $original_simple_getter = __PACKAGE__->can ('get_simple'); # spent 2µs making 1 call to UNIVERSAL::can |
| 781 | 1 | 4µs | 1 | 1µs | my $original_simple_setter = __PACKAGE__->can ('set_simple'); # spent 1µs making 1 call to UNIVERSAL::can |
| 782 | |||||
| 783 | 1 | 100ns | my ($resolved_methods, $cag_produced_crefs); | ||
| 784 | |||||
| 785 | sub CLONE { | ||||
| 786 | my @crefs = grep { defined $_ } values %{$cag_produced_crefs||{}}; | ||||
| 787 | $cag_produced_crefs = @crefs | ||||
| 788 | ? { map { $_ => $_ } @crefs } | ||||
| 789 | : undef | ||||
| 790 | ; | ||||
| 791 | } | ||||
| 792 | |||||
| 793 | # Note!!! Unusual signature | ||||
| 794 | # spent 490ms (46.7+443) within Class::Accessor::Grouped::__ANON__[/usr/share/perl5/Class/Accessor/Grouped.pm:942] which was called 3938 times, avg 124µs/call:
# 3938 times (46.7ms+443ms) by Class::Accessor::Grouped::make_group_accessor at line 530, avg 124µs/call | ||||
| 795 | 3938 | 2.14ms | my ($type, $class, $group, $field, $methname) = @_; | ||
| 796 | 3938 | 1.10ms | $class = ref $class if length ref $class; | ||
| 797 | |||||
| 798 | # When installing an XSA simple accessor, we need to make sure we are not | ||||
| 799 | # short-circuiting a (compile or runtime) get_simple/set_simple override. | ||||
| 800 | # What we do here is install a lazy first-access check, which will decide | ||||
| 801 | # the ultimate coderef being placed in the accessor slot | ||||
| 802 | # | ||||
| 803 | # Also note that the *original* class will always retain this shim, as | ||||
| 804 | # different branches inheriting from it may have different overrides. | ||||
| 805 | # Thus the final method (properly labeled and all) is installed in the | ||||
| 806 | # calling-package's namespace | ||||
| 807 | 3938 | 25.5ms | if ($USE_XS and $group eq 'simple') { | ||
| 808 | die sprintf( "Class::XSAccessor requested but not available:\n%s\n", __CAG_ENV__::NO_CXSA ) | ||||
| 809 | if __CAG_ENV__::NO_CXSA; | ||||
| 810 | |||||
| 811 | # spent 167µs (49+118) within DBIx::Class::Storage::schema which was called:
# once (49µs+118µs) by DBIx::Class::Storage::set_schema at line 74 of DBIx/Class/Storage.pm
# spent 122µs (42+80) within DBIx::Class::ResultSource::_relationships which was called:
# once (42µs+80µs) by DBIx::Class::ResultSource::add_relationship at line 1349 of DBIx/Class/ResultSource.pm
# spent 206µs (85+120) within DBIx::Class::Storage::DBI::on_connect_call which was called:
# once (85µs+120µs) by DBIx::Class::Storage::DBI::mysql::_run_connection_actions at line 1063 of DBIx/Class/Storage/DBI.pm
# spent 94µs (33+61) within DBIx::Class::Storage::DBI::_dbic_connect_attributes which was called 3 times, avg 31µs/call:
# once (32µs+61µs) by DBIx::Class::Storage::DBI::connect_info at line 671 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::mysql::_run_connection_actions at line 94 of DBIx/Class/Storage/DBI/mysql.pm
# once (400ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 913
# spent 120µs (34+87) within DBIx::Class::Row::in_storage which was called:
# once (34µs+87µs) by DBIx::Class::Row::inflate_result at line 1312 of DBIx/Class/Row.pm
# spent 96µs (35+61) within DBIx::Class::ResultSource::_columns which was called:
# once (35µs+61µs) by DBIx::Class::ResultSource::add_columns at line 332 of DBIx/Class/ResultSource.pm
# spent 96µs (35+61) within DBIx::Class::Storage::DBI::_dbh which was called 11 times, avg 9µs/call:
# 2 times (1µs+0s) by DBIx::Class::Storage::DBI::mysql::_run_connection_actions at line 94 of DBIx/Class/Storage/DBI/mysql.pm, avg 600ns/call
# once (27µs+61µs) by Koha::Objects::find at line 960 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::_populate_dbh at line 1046 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::_execute at line 1811 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::_populate_dbh at line 1058 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::_get_dbh at line 969 of DBIx/Class/Storage/DBI.pm
# once (800ns+0s) by DBIx::Class::Storage::DBI::_determine_driver at line 1254 of DBIx/Class/Storage/DBI.pm
# once (500ns+0s) by DBIx::Class::Storage::DBI::_populate_dbh at line 1039 of DBIx/Class/Storage/DBI.pm
# once (400ns+0s) by DBIx::Class::Storage::DBI::_determine_driver at line 1255 of DBIx/Class/Storage/DBI.pm
# once (400ns+0s) by Koha::Objects::find at line 913
# spent 112µs (41+71) within DBIx::Class::Storage::DBI::_conn_pid which was called 3 times, avg 37µs/call:
# once (38µs+71µs) by DBIx::Class::Storage::DBI::_populate_dbh at line 1048 of DBIx/Class/Storage/DBI.pm
# once (2µs+0s) by DBIx::Class::Storage::DBI::_verify_pid at line 271 of DBIx/Class/Storage/DBI.pm
# once (700ns+0s) by DBIx::Class::Storage::DBI::_populate_dbh at line 913
# spent 190µs (48+142) within DBIx::Class::ResultSource::name which was called:
# once (48µs+142µs) by DBIx::Class::ResultSourceProxy::Table::table at line 104 of DBIx/Class/ResultSourceProxy/Table.pm
# spent 102µs (34+69) within DBIx::Class::Storage::transaction_depth which was called:
# once (34µs+69µs) by DBIx::Class::Storage::DBI::dbh_do at line 837 of DBIx/Class/Storage/DBI.pm
# spent 882µs (41+842) within DBIx::Class::ResultSource::_primaries which was called:
# once (41µs+842µs) by DBIx::Class::ResultSource::set_primary_key at line 617 of DBIx/Class/ResultSource.pm
# spent 86µs (31+56) within DBIx::Class::Storage::DBI::_sql_maker which was called 5 times, avg 17µs/call:
# once (26µs+56µs) by DBIx::Class::Storage::DBI::connect_info at line 659 of DBIx/Class/Storage/DBI.pm
# once (2µs+0s) by DBIx::Class::Storage::DBI::sql_maker at line 1021 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::sql_maker at line 979 of DBIx/Class/Storage/DBI.pm
# once (600ns+0s) by DBIx::Class::Storage::DBI::sql_maker at line 1030 of DBIx/Class/Storage/DBI.pm
# once (500ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 913
# spent 111µs (31+80) within DBIx::Class::Storage::DBI::_connect_info which was called 3 times, avg 37µs/call:
# once (30µs+80µs) by DBIx::Class::Storage::DBI::connect_info at line 620 of DBIx/Class/Storage/DBI.pm
# once (600ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 673 of DBIx/Class/Storage/DBI.pm
# once (400ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 913
# spent 98µs (30+69) within DBIx::Class::ResultSource::_ordered_columns which was called:
# once (30µs+69µs) by DBIx::Class::ResultSource::add_columns at line 329 of DBIx/Class/ResultSource.pm
# spent 124µs (40+84) within DBIx::Class::Storage::debug which was called:
# once (40µs+84µs) by DBIx::Class::Storage::DBI::_query_start at line 1764 of DBIx/Class/Storage/DBI.pm
# spent 102µs (35+67) within DBIx::Class::Storage::DBI::_sql_maker_opts which was called 4 times, avg 26µs/call:
# once (31µs+67µs) by DBIx::Class::Storage::DBI::new at line 193 of DBIx/Class/Storage/DBI.pm
# once (3µs+0s) by DBIx::Class::Storage::DBI::sql_maker at line 982 of DBIx/Class/Storage/DBI.pm
# once (900ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 660 of DBIx/Class/Storage/DBI.pm
# once (500ns+0s) by DBIx::Class::Storage::DBI::new at line 913
# spent 119µs (46+73) within DBIx::Class::ResultSet::result_source which was called 8 times, avg 15µs/call:
# 2 times (40µs+73µs) by Koha::Objects::find at line 783 of DBIx/Class/ResultSet.pm, avg 56µs/call
# once (2µs+0s) by DBIx::Class::ResultSet::single at line 1099 of DBIx/Class/ResultSet.pm
# once (1µs+0s) by DBIx::Class::ResultSet::_construct_results at line 1267 of DBIx/Class/ResultSet.pm
# once (1µs+0s) by Koha::Objects::find at line 842 of DBIx/Class/ResultSet.pm
# once (900ns+0s) by DBIx::Class::ResultSet::search_rs at line 432 of DBIx/Class/ResultSet.pm
# once (600ns+0s) by Koha::Objects::find at line 913
# once (500ns+0s) by DBIx::Class::ResultSet::_resolved_attrs at line 3516 of DBIx/Class/ResultSet.pm
# spent 97µs (35+62) within DBIx::Class::Storage::DBI::_dbh_details which was called 6 times, avg 16µs/call:
# once (29µs+62µs) by DBIx::Class::Storage::DBI::new at line 194 of DBIx/Class/Storage/DBI.pm
# once (2µs+0s) by DBIx::Class::Storage::DBI::_server_info at line 1150 of DBIx/Class/Storage/DBI.pm
# once (2µs+0s) by DBIx::Class::Storage::DBI::_server_info at line 1112 of DBIx/Class/Storage/DBI.pm
# once (800ns+0s) by DBIx::Class::Storage::DBI::_dbi_attrs_for_bind at line 1788 of DBIx/Class/Storage/DBI.pm
# once (800ns+0s) by DBIx::Class::Storage::DBI::_populate_dbh at line 1041 of DBIx/Class/Storage/DBI.pm
# once (400ns+0s) by DBIx::Class::Storage::DBI::new at line 913
# spent 169µs (59+110) within DBIx::Class::Storage::DBI::_dbh_autocommit which was called 3 times, avg 56µs/call:
# once (57µs+110µs) by DBIx::Class::Storage::DBI::_connect at line 1531 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::_populate_dbh at line 1054 of DBIx/Class/Storage/DBI.pm
# once (600ns+0s) by DBIx::Class::Storage::DBI::_connect at line 913
# spent 96µs (31+65) within DBIx::Class::ResultSource::_unique_constraints which was called:
# once (31µs+65µs) by DBIx::Class::ResultSource::unique_constraints at line 872 of DBIx/Class/ResultSource.pm
# spent 163µs (50+113) within DBIx::Class::Storage::DBI::disable_sth_caching which was called:
# once (50µs+113µs) by DBIx::Class::Storage::DBI::_prepare_sth at line 1846 of DBIx/Class/Storage/DBI.pm
# spent 162µs (53+109) within DBIx::Class::ResultSet::_result_class which was called 5 times, avg 32µs/call:
# 2 times (50µs+109µs) by DBIx::Class::ResultSet::result_class at line 1569 of DBIx/Class/ResultSet.pm, avg 80µs/call
# once (1µs+0s) by DBIx::Class::ResultSet::_construct_results at line 1367 of DBIx/Class/ResultSet.pm
# once (900ns+0s) by DBIx::Class::ResultSet::result_class at line 1573 of DBIx/Class/ResultSet.pm
# once (700ns+0s) by DBIx::Class::ResultSet::result_class at line 913
# spent 85µs (28+57) within DBIx::Class::Storage::DBI::unsafe which was called 3 times, avg 28µs/call:
# once (26µs+57µs) by DBIx::Class::Storage::DBI::connect_info at line 652 of DBIx/Class/Storage/DBI.pm
# once (2µs+0s) by Try::Tiny::try at line 1501 of DBIx/Class/Storage/DBI.pm
# once (400ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 913
# spent 155µs (48+107) within DBIx::Class::ResultSource::source_name which was called:
# once (48µs+107µs) by DBIx::Class::Schema::load_namespaces at line 279 of DBIx/Class/Schema.pm
# spent 91µs (31+61) within DBIx::Class::Storage::DBI::on_connect_do which was called 3 times, avg 30µs/call:
# once (29µs+61µs) by DBIx::Class::Storage::DBI::connect_info at line 652 of DBIx/Class/Storage/DBI.pm
# once (1µs+0s) by DBIx::Class::Storage::DBI::_parse_connect_do at line 779 of DBIx/Class/Storage/DBI.pm
# once (400ns+0s) by DBIx::Class::Storage::DBI::connect_info at line 913
# spent 91µs (39+52) within DBIx::Class::Storage::DBI::_driver_determined which was called 3 times, avg 30µs/call:
# once (36µs+52µs) by DBIx::Class::Storage::DBI::_determine_driver at line 1248 of DBIx/Class/Storage/DBI.pm
# once (2µs+0s) by DBIx::Class::Storage::DBI::_determine_driver at line 1284 of DBIx/Class/Storage/DBI.pm
# once (500ns+0s) by DBIx::Class::Storage::DBI::_determine_driver at line 913 | ||||
| 812 | 26 | 28µs | my $current_class = length (ref ($_[0] ) ) ? ref ($_[0]) : $_[0]; | ||
| 813 | |||||
| 814 | 26 | 45µs | my $resolved_implementation = $resolved_methods->{$current_class}{$methname} ||= do { | ||
| 815 | 26 | 370µs | 52 | 169µs | if ( # spent 169µs making 52 calls to UNIVERSAL::can, avg 3µs/call |
| 816 | ($current_class->can('get_simple')||0) == $original_simple_getter | ||||
| 817 | && | ||||
| 818 | ($current_class->can('set_simple')||0) == $original_simple_setter | ||||
| 819 | ) { | ||||
| 820 | # nothing has changed, might as well use the XS crefs | ||||
| 821 | # | ||||
| 822 | # note that by the time this code executes, we already have | ||||
| 823 | # *objects* (since XSA works on 'simple' only by definition). | ||||
| 824 | # If someone is mucking with the symbol table *after* there | ||||
| 825 | # are some objects already - look! many, shiny pieces! :) | ||||
| 826 | # | ||||
| 827 | # The weird breeder thingy is because XSA does not have an | ||||
| 828 | # interface returning *just* a coderef, without installing it | ||||
| 829 | # anywhere :( | ||||
| 830 | 26 | 110µs | 26 | 2.50ms | Class::XSAccessor->import( # spent 2.50ms making 26 calls to Class::XSAccessor::import, avg 96µs/call |
| 831 | replace => 1, | ||||
| 832 | class => '__CAG__XSA__BREEDER__', | ||||
| 833 | $maker_templates->{$type}{cxsa_call} => { | ||||
| 834 | $methname => $field, | ||||
| 835 | }, | ||||
| 836 | ); | ||||
| 837 | 26 | 140µs | 26 | 39µs | __CAG__XSA__BREEDER__->can($methname); # spent 39µs making 26 calls to UNIVERSAL::can, avg 2µs/call |
| 838 | } | ||||
| 839 | else { | ||||
| 840 | if (! $xsa_autodetected and ! $no_xsa_warned_classes->{$current_class}++) { | ||||
| 841 | # not using Carp since the line where this happens doesn't mean much | ||||
| 842 | warn 'Explicitly requested use of Class::XSAccessor disabled for objects of class ' | ||||
| 843 | . "'$current_class' inheriting from '$class' due to an overriden get_simple and/or " | ||||
| 844 | . "set_simple\n"; | ||||
| 845 | } | ||||
| 846 | |||||
| 847 | do { | ||||
| 848 | # that's faster than local | ||||
| 849 | $USE_XS = 0; | ||||
| 850 | my $c = $gen_accessor->($type, $class, 'simple', $field, $methname); | ||||
| 851 | $USE_XS = 1; | ||||
| 852 | $c; | ||||
| 853 | }; | ||||
| 854 | } | ||||
| 855 | }; | ||||
| 856 | |||||
| 857 | # if after this shim was created someone wrapped it with an 'around', | ||||
| 858 | # we can not blindly reinstall the method slot - we will destroy the | ||||
| 859 | # wrapper. Silently chain execution further... | ||||
| 860 | 26 | 145µs | 26 | 41µs | if ( ! $cag_produced_crefs->{ $current_class->can($methname) || 0 } ) { # spent 41µs making 26 calls to UNIVERSAL::can, avg 2µs/call |
| 861 | |||||
| 862 | # older perls segfault if the cref behind the goto throws | ||||
| 863 | # http://rt.perl.org/rt3/Public/Bug/Display.html?id=35878 | ||||
| 864 | return $resolved_implementation->(@_) if __CAG_ENV__::BROKEN_GOTO; | ||||
| 865 | |||||
| 866 | goto $resolved_implementation; | ||||
| 867 | } | ||||
| 868 | |||||
| 869 | |||||
| 870 | if (__CAG_ENV__::TRACK_UNDEFER_FAIL) { | ||||
| 871 | my $deferred_calls_seen = do { | ||||
| 872 | 2 | 123µs | 2 | 23µs | # spent 17µs (10+6) within Class::Accessor::Grouped::BEGIN@872 which was called:
# once (10µs+6µs) by base::import at line 872 # spent 17µs making 1 call to Class::Accessor::Grouped::BEGIN@872
# spent 6µs making 1 call to strict::unimport |
| 873 | \%{"${current_class}::__cag_deferred_xs_shim_invocations"} | ||||
| 874 | }; | ||||
| 875 | my @cframe = caller(0); | ||||
| 876 | |||||
| 877 | if (my $already_seen = $deferred_calls_seen->{$cframe[3]}) { | ||||
| 878 | Carp::carp ( | ||||
| 879 | "Deferred version of method $cframe[3] invoked more than once (originally " | ||||
| 880 | . "invoked at $already_seen). This is a strong indication your code has " | ||||
| 881 | . 'cached the original ->can derived method coderef, and is using it instead ' | ||||
| 882 | . 'of the proper method re-lookup, causing minor performance regressions' | ||||
| 883 | ); | ||||
| 884 | } | ||||
| 885 | else { | ||||
| 886 | $deferred_calls_seen->{$cframe[3]} = "$cframe[1] line $cframe[2]"; | ||||
| 887 | } | ||||
| 888 | } | ||||
| 889 | |||||
| 890 | # install the resolved implementation into the code slot so we do not | ||||
| 891 | # come here anymore (hopefully) | ||||
| 892 | # since XSAccessor was available - so is Sub::Name | ||||
| 893 | { | ||||
| 894 | 28 | 44µs | 2 | 21µs | # spent 16µs (11+5) within Class::Accessor::Grouped::BEGIN@894 which was called:
# once (11µs+5µs) by base::import at line 894 # spent 16µs making 1 call to Class::Accessor::Grouped::BEGIN@894
# spent 5µs making 1 call to strict::unimport |
| 895 | 2 | 301µs | 2 | 28µs | # spent 19µs (9+10) within Class::Accessor::Grouped::BEGIN@895 which was called:
# once (9µs+10µs) by base::import at line 895 # spent 19µs making 1 call to Class::Accessor::Grouped::BEGIN@895
# spent 10µs making 1 call to warnings::unimport |
| 896 | |||||
| 897 | 26 | 24µs | my $fq_name = "${current_class}::${methname}"; | ||
| 898 | 26 | 219µs | 26 | 91µs | *$fq_name = Sub::Name::subname($fq_name, $resolved_implementation); # spent 91µs making 26 calls to Sub::Name::subname, avg 4µs/call |
| 899 | } | ||||
| 900 | |||||
| 901 | # now things are installed - one ref less to carry | ||||
| 902 | 26 | 21µs | delete $resolved_methods->{$current_class}{$methname}; | ||
| 903 | |||||
| 904 | # but need to record it in the expectation registry *in case* it | ||||
| 905 | # was cached via ->can for some moronic reason | ||||
| 906 | 26 | 134µs | 26 | 30µs | Scalar::Util::weaken( $cag_produced_crefs->{$resolved_implementation} = $resolved_implementation ); # spent 30µs making 26 calls to Scalar::Util::weaken, avg 1µs/call |
| 907 | |||||
| 908 | |||||
| 909 | # older perls segfault if the cref behind the goto throws | ||||
| 910 | # http://rt.perl.org/rt3/Public/Bug/Display.html?id=35878 | ||||
| 911 | return $resolved_implementation->(@_) if __CAG_ENV__::BROKEN_GOTO; | ||||
| 912 | |||||
| 913 | 26 | 517µs | 26 | 48µs | goto $resolved_implementation; # spent 35µs making 1 call to DBIx::Class::Storage::DBI::mysql::debug
# spent 1µs making 1 call to DBIx::Class::Storage::DBI::mysql::on_connect_call
# spent 700ns making 1 call to DBIx::Class::ResultSet::_result_class
# spent 700ns making 1 call to DBIx::Class::Storage::DBI::_conn_pid
# spent 600ns making 1 call to DBIx::Class::ResultSet::result_source
# spent 600ns making 1 call to DBIx::Class::Storage::DBI::_dbh_autocommit
# spent 600ns making 1 call to DBIx::Class::Storage::DBI::schema
# spent 500ns making 1 call to DBIx::Class::ResultSource::Table::_primaries
# spent 500ns making 1 call to DBIx::Class::ResultSource::Table::_unique_constraints
# spent 500ns making 1 call to DBIx::Class::ResultSource::Table::name
# spent 500ns making 1 call to DBIx::Class::ResultSource::Table::source_name
# spent 500ns making 1 call to DBIx::Class::Storage::DBI::_driver_determined
# spent 500ns making 1 call to DBIx::Class::Storage::DBI::_sql_maker
# spent 500ns making 1 call to DBIx::Class::Storage::DBI::_sql_maker_opts
# spent 500ns making 1 call to Koha::Schema::Result::Branch::in_storage
# spent 400ns making 1 call to DBIx::Class::ResultSource::Table::_columns
# spent 400ns making 1 call to DBIx::Class::ResultSource::Table::_ordered_columns
# spent 400ns making 1 call to DBIx::Class::ResultSource::Table::_relationships
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::_connect_info
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::_dbh
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::_dbh_details
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::_dbic_connect_attributes
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::mysql::disable_sth_caching
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::mysql::transaction_depth
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::on_connect_do
# spent 400ns making 1 call to DBIx::Class::Storage::DBI::unsafe |
| 914 | 84 | 320µs | }; | ||
| 915 | |||||
| 916 | 84 | 465µs | 84 | 132µs | Scalar::Util::weaken($cag_produced_crefs->{$ret} = $ret); # spent 132µs making 84 calls to Scalar::Util::weaken, avg 2µs/call |
| 917 | |||||
| 918 | 84 | 70µs | $ret; # returning shim | ||
| 919 | } | ||||
| 920 | |||||
| 921 | # no Sub::Name - just install the coderefs directly (compiling every time) | ||||
| 922 | elsif (__CAG_ENV__::NO_SUBNAME) { | ||||
| 923 | my $src = $accessor_maker_cache->{source}{$type}{$group}{$field} ||= | ||||
| 924 | $maker_templates->{$type}{pp_generator}->($group, $field); | ||||
| 925 | |||||
| 926 | $cag_eval->( | ||||
| 927 | "no warnings 'redefine'; sub ${class}::${methname} { $src }; 1", | ||||
| 928 | ); | ||||
| 929 | |||||
| 930 | undef; # so that no further attempt will be made to install anything | ||||
| 931 | } | ||||
| 932 | |||||
| 933 | # a coderef generator with a variable pad (returns a fresh cref on every invocation) | ||||
| 934 | else { | ||||
| 935 | 3854 | 14.5ms | 3854 | 14.0ms | ($accessor_maker_cache->{pp}{$type}{$group}{$field} ||= do { # spent 14.0ms making 3854 calls to Class::Accessor::Grouped::__ANON__[(eval 1000)[Class/Accessor/Grouped.pm:764]:5], avg 4µs/call |
| 936 | 927 | 2.34ms | 927 | 8.87ms | my $src = $accessor_maker_cache->{source}{$type}{$group}{$field} ||= # spent 8.87ms making 927 calls to Class::Accessor::Grouped::__ANON__[Class/Accessor/Grouped.pm:708], avg 10µs/call |
| 937 | $maker_templates->{$type}{pp_generator}->($group, $field); | ||||
| 938 | |||||
| 939 | 927 | 1.81ms | 927 | 420ms | $cag_eval->( "sub { my \$dummy; sub { \$dummy if 0; $src } }" ); # spent 420ms making 927 calls to Class::Accessor::Grouped::__ANON__[Class/Accessor/Grouped.pm:774], avg 454µs/call |
| 940 | })->() | ||||
| 941 | } | ||||
| 942 | 1 | 2µs | }; | ||
| 943 | |||||
| 944 | 1 | 10µs | 1; | ||
# spent 5.02ms within Class::Accessor::Grouped::CORE:match which was called 3939 times, avg 1µs/call:
# 1969 times (4.09ms+0s) by Class::Accessor::Grouped::_mk_group_accessors at line 97, avg 2µs/call
# 1969 times (931µs+0s) by Class::Accessor::Grouped::_mk_group_accessors at line 137, avg 473ns/call
# once (3µs+0s) by base::import at line 19 | |||||
# spent 846µs within DBIx::Class::ResultSource::CORE:match which was called 650 times, avg 1µs/call:
# 325 times (594µs+0s) by DBIx::Class::ResultSource::add_relationship at line 1343 of DBIx/Class/ResultSource.pm, avg 2µs/call
# 325 times (251µs+0s) by DBIx::Class::ResultSource::add_relationship at line 1346 of DBIx/Class/ResultSource.pm, avg 774ns/call | |||||
# spent 557µs within DBIx::Class::ResultSource::CORE:subst which was called 1602 times, avg 348ns/call:
# 1602 times (557µs+0s) by DBIx::Class::ResultSource::add_columns at line 335 of DBIx/Class/ResultSource.pm, avg 348ns/call | |||||
# spent 10µs within DBIx::Class::Storage::DBI::CORE:match which was called 2 times, avg 5µs/call:
# once (6µs+0s) by DBIx::Class::Storage::DBI::_server_info at line 1130 of DBIx/Class/Storage/DBI.pm
# once (4µs+0s) by DBIx::Class::Storage::DBI::_dbh_get_info at line 1163 of DBIx/Class/Storage/DBI.pm | |||||
# spent 600ns within DBIx::Class::Storage::DBI::schema which was called:
# once (600ns+0s) by DBIx::Class::Storage::set_schema at line 913 | |||||
sub __CAG_ENV__::__ANON__; # xsub |