X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FLaTeX%2FTikZ%2FFunctor%2FRule.pm;h=7c55061b4de8e5fd2dd4bf4cc10c09e2bc204a54;hb=61a93a58351bf2d238dcf81a1a557112b0c0ee85;hp=df5b553eb5a7256dd7e253f029c75f16d42a230f;hpb=bc1f84f569da48d9d070384eb1bcccac289931e5;p=perl%2Fmodules%2FLaTeX-TikZ.git diff --git a/lib/LaTeX/TikZ/Functor/Rule.pm b/lib/LaTeX/TikZ/Functor/Rule.pm index df5b553..7c55061 100644 --- a/lib/LaTeX/TikZ/Functor/Rule.pm +++ b/lib/LaTeX/TikZ/Functor/Rule.pm @@ -24,9 +24,9 @@ A functor is basically an ordered collection of rules. use Carp (); -use Any::Moose; -use Any::Moose 'Util' => [ qw[find_meta does_role] ]; -use Any::Moose 'Util::TypeConstraints'; +use Mouse; +use Mouse::Util qw; +use Mouse::Util::TypeConstraints; =head1 ATTRIBUTES @@ -85,7 +85,12 @@ my $ltfrl_tc = subtype 'LaTeX::TikZ::Functor::RuleList' =head1 METHODS -=head2 C<< new target => $target, handler => $handler >> +=head2 C + + my $rule = LaTeX::TikZ::Functor::Rule->new( + target => $target, + handler => $handler, + ); Constructs a new rule object with target C<$target> and handler C<$handler>. @@ -105,7 +110,7 @@ around 'BUILDARGS' => sub { my $meta = find_meta($target); Carp::confess("No meta object associated with target $target") unless defined $meta; - $args{is_role} = $meta->isa(any_moose('Meta::Role')); + $args{is_role} = $meta->isa('Mouse::Meta::Role'); my $is_set; if (does_role($target, 'LaTeX::TikZ::Set')) { @@ -120,15 +125,24 @@ around 'BUILDARGS' => sub { $class->$orig(%args); }; -=head2 C<< insert into => \@list, overwrite => $overwrite, replace => $replace >> +=head2 C + + my $has_replaced = $rule->insert( + into => \@list, + overwrite => $overwrite, + replace => $replace, + ); Inserts the current rule into the list of rules C<@list>. +The list is expected to be ordered, in that each rule must come after all the rules that have a target that inherits or consumes the original rule's own target. -If C<$replace> is false, then the rule will be appended to the C<@list> ; except if there already is an existent entry for the same target, in which case it will be overwritten if C<$overwrite> is true, or an exception will be thrown if it is false. +If C<$replace> is false, then the rule will be inserted into C<@list> after all the rules applying to the target's subclasses/subroles and before all its superclasses/superroles ; except if there is already an existent entry for the same target, in which case it will be overwritten if C<$overwrite> is true, or an exception will be thrown if it is false. If C<$replace> is true, then the rule will replace the first rule in the list that is a subclass or that consumes the role denoted by the target. All the subsequent rules in the list that inherit or consume the target will be removed. +Returns true if and only if an existent rule was replaced. + =cut sub insert { @@ -140,9 +154,6 @@ sub insert { my $overwrite = $args{overwrite}; my $replace = $args{replace}; - my $target = $rule->target; - my $is_role = $rule->is_role; - if ($replace) { my (@remove, $replaced); @@ -166,23 +177,48 @@ sub insert { return 1 if $replaced; } else { # Replace only an existent rule + my $target = $rule->target; + + my $last_descendant = undef; + my $first_ancestor = undef; for my $i (0 .. $#$list) { - my $old_target = $list->[$i]->target; + my $old_rule = $list->[$i]; + my $old_target = $old_rule->target; if ($old_target eq $target) { Carp::confess("Default rule already defined for target $target") unless $overwrite; splice @$list, $i, 1, $rule; return 1; + } elsif ($rule->handles($old_target)) { + $last_descendant = $i; + } elsif ($old_rule->handles($target)) { + $first_ancestor = $i; } } + + my $pos; + if (defined $first_ancestor) { + Carp::confess("Unsorted rule list") + if defined $last_descendant and $first_ancestor <= $last_descendant; + $pos = $first_ancestor; + } elsif (defined $last_descendant) { + $pos = $last_descendant + 1; + } + + if (defined $pos) { + splice @$list, $pos, 0, $rule; + return 0; + } } push @$list, $rule; return 0; } -=head2 C +=head2 C + + $rule->handles($obj); Returns true if and only if the current rule can handle the object or class/role name C<$obj>. @@ -219,7 +255,7 @@ You can find documentation for this module with the perldoc command. =head1 COPYRIGHT & LICENSE -Copyright 2010 Vincent Pit, all rights reserved. +Copyright 2010,2011,2012,2013,2014,2015 Vincent Pit, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.