Skip Menu |

This queue is for tickets about the Iterator CPAN distribution.

Report information
The Basics
Id: 50214
Status: new
Priority: 0/
Queue: Iterator

People
Owner: Nobody in particular
Requestors: NCLEATON [...] cpan.org
Cc:
AdminCc:

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



Subject: [PATCH] delay code call until result is needed (fixes #37492 and #47109)
This patch delays the call to the user code until the result is needed to satisfy a value(), is_exhaused() or isnt_exhausted() call. This eliminates some duplicated code, and fixes #37492 and #47109 - I've included the test scripts from those tickets, they now pass.
Subject: Iterator.patch
diff -Nurd Iterator-0.03-orig/Iterator.pm Iterator-0.03/Iterator.pm --- Iterator-0.03-orig/Iterator.pm 2005-10-10 06:03:00.000000000 +0200 +++ Iterator-0.03/Iterator.pm 2009-10-05 15:55:50.000000000 +0200 @@ -162,24 +162,6 @@ $code_for {$self} = $code; - # Get the next (first) value for this iterator - eval - { - $next_value_for{$self} = $code-> (); - }; - - my $ex; - if ($ex = Iterator::X::Am_Now_Exhausted->caught ()) - { - # Starting off exhausted is okay - $is_exhausted{$self} = 1; - } - elsif ($@) - { - Iterator::X::User_Code_Error->throw (message => "$@", - eval_error => $@); - } - return; } @@ -215,13 +197,17 @@ { my $self = shift; + exists $next_value_for{$self} or $self->_fetch; + Iterator::X::Exhausted->throw(q{Iterator is exhausted}) if $is_exhausted{$self}; - # The value that we'll be returning this time. - my $this_value = $next_value_for{$self}; + return delete $next_value_for{$self}; + } + + sub _fetch { + my $self = shift; - # Compute the value that we'll return next time eval { $next_value_for{$self} = $code_for{$self}->(@_); @@ -230,14 +216,13 @@ { # Aha, we're done; we'll have to stop next time. $is_exhausted{$self} = 1; + $next_value_for{$self} = undef; } elsif ($@) { Iterator::X::User_Code_Error->throw (message => "$@", eval_error => $@); } - - return $this_value; } # Method name: is_exhausted @@ -251,7 +236,9 @@ { my $self = shift; - return $is_exhausted{$self}; + exists $next_value_for{$self} or $self->_fetch; + return 1 if $is_exhausted{$self}; + return; } # Method name: isnt_exhausted @@ -265,7 +252,7 @@ { my $self = shift; - return ! $is_exhausted{$self}; + return ! $self->is_exhausted; } } # end of encapsulation enclosure diff -Nurd Iterator-0.03-orig/t/rt37492.t Iterator-0.03/t/rt37492.t --- Iterator-0.03-orig/t/rt37492.t 1970-01-01 02:00:00.000000000 +0200 +++ Iterator-0.03/t/rt37492.t 2009-10-05 16:10:59.000000000 +0200 @@ -0,0 +1,18 @@ + +use strict; +use warnings; + +use Iterator; +use Test::More; + +my $value = 0; +my $foo = Iterator->new( sub { return ++$value } ); + +plan(tests=>4); +is($foo->value(),1); +is($foo->value(),2); + +# Reset value we're keying off to something else entirely. +$value = 20; +is($foo->value(),21); +is($foo->value(),22); diff -Nurd Iterator-0.03-orig/t/rt47109.t Iterator-0.03/t/rt47109.t --- Iterator-0.03-orig/t/rt47109.t 1970-01-01 02:00:00.000000000 +0200 +++ Iterator-0.03/t/rt47109.t 2009-10-05 16:16:45.000000000 +0200 @@ -0,0 +1,8 @@ +use Test::More tests => 1; +use Iterator; + +my $value = 0; + +my $iterator = new Iterator(sub { return ++$value }); + +is($value, 0, "Haven't called the iterator yet."); diff -Nurd Iterator-0.03-orig/t/value.t Iterator-0.03/t/value.t --- Iterator-0.03-orig/t/value.t 2005-10-10 06:03:00.000000000 +0200 +++ Iterator-0.03/t/value.t 2009-10-05 16:04:55.000000000 +0200 @@ -1,5 +1,5 @@ use strict; -use Test::More tests => 33; +use Test::More tests => 35; use Iterator; # Check that value() works. @@ -163,6 +163,13 @@ { $val = $iter->value; }; +is ($@, q{}, q{User-error iterator; second value no error.}); +cmp_ok ($val, '==', 2, q{User-error iterator; second value correct}); + +eval +{ + $val = $iter->value; +}; isnt ($@, q{}, q{User-error iterator blew up on time}); $x = $@; ok (Iterator::X->caught(), q{User-error base exception caught});