I'm puzzling over the best interface design of a multi-purpose function/operator, where the same function can be used for various purposes:
Lets take a function range() simulating the range operator as example:
for ( range(1,9) ) { print $i }
while ( range(1,9) ) {...}
$f=range(1,9); while ( &$f ) {...}
should all do the same 9 loops.
The first two examples are easy to achieve by evaluating the context (for imposes list, while scalar context).
Unfortunately there is no "function context"...
I was thinking about blessing a scalar such that I can use scalar context for both cases, such that
$f=range(1,9); while ( $i=$f->next ) {...} works.
Anyhow this is sabotaging performance, since calling methods on objects or ties is quite expensive... and I'm not sure if this double nature of $f could have ugly side effects.
The other approach would be using globs, such that calling *f=range(1,9); while ( $i=f() ) {...} would define a function f(), but ATM I'm not sure if this is even possible...and it shouldn't be working with lexical functions.
My best guess is to return a blessed scalar and to use this $f=range(1,9)->iterator; while ( $i=&$f ) {...} ...
Any suggestions?
That's all untested code, hope you get the underlying ideas.
Cheers Rolf
PS: Yes I know that the while loops wouldn't work when range(0,9) is called, but thats another issue. I didn't want to over complicate the examples... :)
UPDATE:
After some meditation I think I got an even better idea, I could check for a third parameter to assign the scalar value to, such that in scalar context always a coderef is returned, this would also solve the "0 problem" (see PS):
for my $i ( range(1,9) ) { print $i }
while ( range 1,9 => my $i ) {...}
$f=range(1,9); while ( $f->(my $i)) {...}
UPDATE:
I think I have to replace all mys with state restricting this feature to 5.10. 8(
In reply to Designing a DWIMish interface for generator function by LanX
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |