Some examples may help...

I would write an iterator without either NEXTVAL() or Iterator() myself. Something like the following:

#!/usr/bin/perl -w use strict; use warnings; sub make_rand { my $x = 0; return sub { return $x++; # not very random }; } my $rng = make_rand(); for my $i (1..4) { my $x = $rng->(); print "$x\n"; }

sub {BLOCK} produces a reference to an anonymous subroutine and make_rand() uses this form as argument to return, returning a reference to an anonymous subroutine.

$rng->() dereferences the subroutine reference and calls the referenced subroutine.

NEXTVAL() does the same thing, but in a subroutine instead of directly. So the following also works:

#!/usr/bin/perl -w use strict; use warnings; sub NEXTVAL { $_[0]->() } sub make_rand { my $x = 0; return sub { return $x++; }; } my $rng = make_rand(); for my $i (1..4) { my $x = NEXTVAL ( $rng ); print "$x\n"; }

Iterator() deals with return sub {block}. You can define Iterator() without the prototype, in which case you would have to explicitly produce a subroutine reference as its argument. The following works:

#!/usr/bin/perl -w use strict; use warnings; sub NEXTVAL { $_[0]->() } sub Iterator { return $_[0] } sub make_rand { my $x = 0; return sub { return Iterator sub { return $x++; }; } my $rng = make_rand(); for my $i (1..4) { my $x = NEXTVAL ( $rng ); print "$x\n"; }

In this case, the reference to the anonymous subroutine is an argument to the subroutine Iterator rather than return, which only sees what Iterator returns. As Iterator returns its first argument without changing it, the reference to the anonymous subroutine is still being returned from make_rand().

Finally, with a prototype on Iterator(), you can dispense with the "sub" in its argument list and simply provide a "{BLOCK}". So the following also works.

#!/usr/bin/perl -w use strict; use warnings; sub NEXTVAL { $_[0]->() } sub Iterator (&) { return $_[0] } sub make_rand { my $x = 0; return Iterator { return $x++; }; } my $rng = make_rand(); for my $i (1..4) { my $x = NEXTVAL ( $rng ); print "$x\n"; }

They all work. The first will be slightly more efficient at run time, but usually not enough to matter. The latter may, depending on your sensibilities, be easier to understand and maintain. You can take your pick and use whichever tickles your fancy.


In reply to Re: "a bit of sugar "(HOP) by ig
in thread "a bit of sugar "(HOP) by Wiggins

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.