Commits

Toby Inkster  committed 49bea6f

Implement a find_parent method.

  • Participants
  • Parent commits 9746eb3

Comments (0)

Files changed (2)

File lib/Type/Tiny.pm

 	return ($self->parent, $self->parent->parents);
 }
 
+sub find_parent
+{
+	my $self = shift;
+	my ($test) = @_;
+	
+	local ($_, $.);
+	my $type  = $self;
+	my $count = 0;
+	while ($type)
+	{
+		if ($test->($_=$type, $.=$count))
+		{
+			return wantarray ? ($type, $count) : $type;
+		}
+		else
+		{
+			$type = $type->parent;
+			$count++;
+		}
+	}
+	
+	return;
+}
+
 sub check
 {
 	my $self = shift;
 as an arrayref in violation of the base class' documentation. I'm keeping
 my behaviour as it seems more useful. >>
 
+=item C<< find_parent($coderef) >>
+
+Loops through the parent type constraints I<< including the invocant
+itself >> and returns the nearest ancestor type constraint where the
+coderef evaluates to true. Within the coderef the ancestor currently
+being checked is C<< $_ >>. Returns undef if there is no match.
+
+In list context also returns the number of type constraints which had
+been looped through before the matching constraint was found.
+
 =item C<< coercibles >>
 
 Return a type constraint which is the union of type constraints that can be

File t/20-unit/Type-Tiny/basic.t

 	);
 }
 
+my $t1 = Types::Standard::Int;
+my $t2 = $t1->create_child_type(name => 'T2');
+my $t3 = $t2->create_child_type(name => 'T3');
+my $t4 = $t3->create_child_type(name => 'T4');
+my $t5 = $t4->create_child_type(name => 'T5');
+my $t6 = $t5->create_child_type(name => 'T6');
+
+my $found = $t6->find_parent(sub {
+	$_->has_parent and $_->parent->name eq 'Int'
+});
+
+is($found->name, 'T2', 'find_parent (scalar context)');
+
+my ($found2, $n) = $t6->find_parent(sub {
+	$_->has_parent and $_->parent->name eq 'Int'
+});
+
+is($found2->name, 'T2', 'find_parent (list context)');
+is($n, 4, '... includes a count');
+
 done_testing;