X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FMethodAttributes.pm;h=6c23988c0380c15ca0d3da6b02cffdf4b3e286bd;hb=09d8fb4a05e6cd025924cc08e41484f17a116695;hp=cea396116cccedd3a802318e6adf7f4b37a9e22e;hpb=5ab7259324b6e3d0feea533239b6d77db0b28c9c;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/MethodAttributes.pm b/lib/DBIx/Class/MethodAttributes.pm index cea3961..6c23988 100644 --- a/lib/DBIx/Class/MethodAttributes.pm +++ b/lib/DBIx/Class/MethodAttributes.pm @@ -6,7 +6,6 @@ use warnings; use DBIx::Class::_Util qw( uniq refdesc visit_namespaces ); use Scalar::Util qw( weaken refaddr ); -use mro 'c3'; use namespace::clean; my ( $attr_cref_registry, $attr_cache_active ); @@ -76,6 +75,16 @@ sub MODIFY_CODE_ATTRIBUTES { weaken( $attr_cref_registry->{$code}{weakref} = $code ) } + + # increment the pkg gen, this ensures the sanity checkers will re-evaluate + # this class when/if the time comes + mro::method_changed_in($class) if ( + ! DBIx::Class::_ENV_::OLD_MRO + and + ( $attrs->{dbic} or $attrs->{misc} ) + ); + + # handle legacy attrs if( $attrs->{misc} ) { @@ -94,6 +103,7 @@ sub MODIFY_CODE_ATTRIBUTES { ))]; } + # handle DBIC_* attrs if( $attrs->{dbic} ) { my $slot = $attr_cref_registry->{$code}; @@ -108,6 +118,7 @@ sub MODIFY_CODE_ATTRIBUTES { ]; } + # FIXME - DBIC essentially gobbles up any attribute it can lay its hands on: # decidedly not cool # @@ -132,8 +143,34 @@ sub MODIFY_CODE_ATTRIBUTES { sub VALID_DBIC_CODE_ATTRIBUTE { #my ($class, $attr) = @_; - # initially no valid attributes - 0; +### +### !!! IMPORTANT !!! +### +### *DO NOT* yield to the temptation of using free-form-argument attributes. +### The technique was proven instrumental in Catalyst a decade ago, and +### was more recently revived in Sub::Attributes. Yet, while on the surface +### they seem immensely useful, per-attribute argument lists are in fact an +### architectural dead end. +### +### In other words: you are *very strongly urged* to ensure the regex below +### does not allow anything beyond qr/^ DBIC_method_is_ [A-Z_a-z0-9]+ $/x +### + + $_[1] =~ /^ DBIC_method_is_ (?: + indirect_sugar + | + generated_from_resultsource_metadata + | + (?: inflated_ | filtered_ )? column_ (?: extra_)? accessor + | + single_relationship_accessor + | + (?: multi | filter ) _relationship_ (?: extra_ )? accessor + | + proxy_to_relationship + | + m2m_ (?: extra_)? sugar (?:_with_attrs)? + ) $/x; } sub FETCH_CODE_ATTRIBUTES { @@ -189,11 +226,108 @@ L below. The following method attributes are currently recognized under the C prefix: -=over +=head3 DBIC_method_is_indirect_sugar -=item * None so far +The presence of this attribute indicates a helper "sugar" method. Overriding +such methods in your subclasses will be of limited success at best, as DBIC +itself and various plugins are much more likely to invoke alternative direct +call paths, bypassing your override entirely. Good examples of this are +L and L. -=back +See also the check +L. + +=head3 DBIC_method_is_generated_from_resultsource_metadata + +This attribute is applied to all methods dynamically installed after various +invocations of L. Notably +this includes L, +L, +L +and the various L, +B the L (given its +effects are never reflected as C). + +=head3 DBIC_method_is_column_accessor + +This attribute is applied to all methods dynamically installed as a result of +invoking L. + +=head3 DBIC_method_is_inflated_column_accessor + +This attribute is applied to all methods dynamically installed as a result of +invoking L. + +=head3 DBIC_method_is_filtered_column_accessor + +This attribute is applied to all methods dynamically installed as a result of +invoking L. + +=head3 DBIC_method_is_*column_extra_accessor + +For historical reasons any L accessor is generated +twice as C<{name}> and C<_{name}_accessor>. The second method is marked with +C correspondingly. + +=head3 DBIC_method_is_single_relationship_accessor + +This attribute is applied to all methods dynamically installed as a result of +invoking L, +L or +L (though for C +see L<...filter_rel...|/DBIC_method_is_filter_relationship_accessor> below. + +=head3 DBIC_method_is_multi_relationship_accessor + +This attribute is applied to the main method dynamically installed as a result +of invoking L. + +=head3 DBIC_method_is_multi_relationship_extra_accessor + +This attribute is applied to the two extra methods dynamically installed as a +result of invoking L: +C<$relname_rs> and C. + +=head3 DBIC_method_is_filter_relationship_accessor + +This attribute is applied to (legacy) methods dynamically installed as a +result of invoking L with an +already-existing identically named column. The method is internally +implemented as an L +and is labeled with both atributes at the same time. + +=head3 DBIC_method_is_filter_relationship_extra_accessor + +Same as L. + +=head3 DBIC_method_is_proxy_to_relationship + +This attribute is applied to methods dynamically installed as a result of +providing L. + +=head3 DBIC_method_is_m2m_sugar + +=head3 DBIC_method_is_m2m_sugar_with_attrs + +One of the above attributes is applied to the main method dynamically +installed as a result of invoking +L. The C<_with_atrs> suffix +serves to indicate whether the user supplied any C<\%attrs> to the +C call. There is deliberately no mechanism to retrieve the actual +supplied values: if you really need this functionality you would need to rely on +L. + +=head3 DBIC_method_is_extra_m2m_sugar + +=head3 DBIC_method_is_extra_m2m_sugar_with_attrs + +One of the above attributes is applied to the extra B methods dynamically +installed as a result of invoking +L: C<$m2m_rs>, C, +C and C. =head1 METHODS