Skip Menu |

This queue is for tickets about the Brick CPAN distribution.

Report information
The Basics
Id: 26369
Status: resolved
Priority: 0/
Queue: Brick

People
Owner: Nobody in particular
Requestors: agianni [...] buffalo.edu
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: __compose_pass_or_skip
Date: Sat, 14 Apr 2007 23:56:59 -0400
To: <bug-Brick [...] rt.cpan.org>
From: Andrew Gianni <agianni [...] buffalo.edu>
I'm having trouble getting logged into RT on CPAN, so I'll try the email interface. I've found what I consider to be a bug in __compose_pass_or_skip. My problem is that when I try to use it in creation of selectors I get fatal errors as would otherwise only be thrown by a constraint. I have put together an updated version of the method as well as a test that will point out my problem with the existing implementation, which is corrected by my update. Currently test four fails in my test, which is the primary issue causing me trouble. The main thing I changed is that the only action taken within the closure is to return when something succeeds. It also keeps track of coderefs that die so it can avoid a final fatal error at the end if nothing passed; i.e. if it's made up of nothing but selectors, it will act as a selector itself. The only think I'm not certain of is what the functionality should be if one were to include both selector and constraint bricks within a call to __compose_pass_or_skip. In the case of both of our implementations it would create a fatal error, which would give constraining bricks more "prescience" as it were. I'm comfortable with this notion, although I have yet to run into a situation where I would want to do such a thing with __compose_pass_or_skip. Please let me know what you think: The test: #!/perl use strict; use warnings; use Carp; use English qw( no_match_vars ); use Brick; use Test::More qw( no_plan ); my $brick = Brick->new(); my $bucket = $brick->create_bucket(); my $coderef = $bucket->__compose_pass_or_skip( sub { croak { message => "failing1" } }, sub { return 1; }, ); eval{ $coderef->() }; ok ( ( not $EVAL_ERROR ), 'success with one croak and one return 1' ); $coderef = $bucket->__compose_pass_or_skip( sub { return 0; }, sub { return 1; }, ); eval{ $coderef->() }; ok ( ( not $EVAL_ERROR ), 'success with one return 0 and one return 1' ); $coderef = $bucket->__compose_pass_or_skip( sub { croak { message => "failing1" } }, sub { croak { message => "failing2" } }, ); eval{ $coderef->() }; ok ( $EVAL_ERROR, 'error generated with two croaks' ); # THIS FAILS WITH THE CURRENT VERSION $coderef = $bucket->__compose_pass_or_skip( sub { return; }, sub { return; }, ); my $result = eval{ $coderef->() }; ok ( ( not $EVAL_ERROR ), 'not eval error with two return 0' ); ok ( ( not $result ), 'returns 0' ); The update: sub __compose_pass_or_skip { my( $bucket, @subs ) = @_; if( grep { ref $_ ne ref sub {} } @subs ) { croak "Got something else when expecting code ref!"; return sub {}; } my @caller = $bucket->__caller_chain_as_list(); my $sub = $bucket->add_to_bucket( { code => sub { my @dies = (); foreach my $sub ( @subs ) { my $result = eval { $sub->( @_ ) }; my $at = $@; return $result if $result; push @dies, $sub if ref $at and $at; } if ( scalar @dies ) { die { message => "Nothing worked! Unexpected failure of all branches", handler => $caller[0]{'sub'}, errors => \@dies, }; } else { return; } }, }); $bucket->comprise( $sub, @subs ); return $sub; }
This is a documentation problem. The __compose_pass_or_skip only skips things that don't die but don't return true. If a sub dies, the composed sub still propogates the death.
Subject: Re: [rt.cpan.org #26369] __compose_pass_or_skip
Date: Tue, 17 Apr 2007 07:21:15 -0400
To: <bug-Brick [...] rt.cpan.org>
From: Andrew Gianni <agianni [...] buffalo.edu>
Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=26369 > > > This is a documentation problem. The __compose_pass_or_skip only skips > things that don't die but don't return true. If a sub dies, the composed > sub still propogates the death.
My problem is that if I compose a brick with __compose_pass_or_skip with selectors only and they all fail, it dies in the end instead of simply returning undef, which is what I would expect. If this was also specifically not your intent that's fine and I'll use my own composer.
Show quoted text
> My problem is that if I compose a brick with __compose_pass_or_skip with > selectors only and they all fail, it dies in the end instead of simply > returning undef, which is what I would expect. If this was also
specifically Show quoted text
> not your intent that's fine and I'll use my own composer.
I think my intent was that something had to run. The error message is "Nothing worked! Unexpected failure of all branches". OF course, this came before selectors. Now, that doesn't mean it's the right thing.
Since I don't need __compose_pass_or_skip to die if nothing passes, and you don't want it to, I took out the die. Now it just returns 0.
Fixed in 0.226_01