Perl Sq: Seq in combination with I/O
In one of my programs I already use my module. This program creates a new test-file in the ’t’ folder from a template. From all files in that directory I want to automatically pick the next highest number. I don’t want to search for the number myself.
So here is how i read all files from disk and only pick files matching the pattern “%d-$title.t”. Then i want the maximum number.
This example shows how you can “connect” to other modules to use them. In this example
its Path::Tiny.
|
|
Here is how it works.
- It begins with
max. maxwants to know the highest numerical value. So he askchoosefor the next value.choosealso don’t know abbout any value, he askmapto give him one.mapalso don’t know about any value, so he askwrapabout one.wrapfinally knows about a value. He gives him the next one, and asks Do you want this?maplooks at it. He says, yes i take all. Then he askschooseis this the basename you wanted?chooselooks at it. He runs a regex on it to proof the correct format, and extract the number from the basename.- When it is the correct format, he gives
maxthe requested file. (goto #8) - When it not the correct format, he throws it away, and asks
mapagain for the next value. (goto #4)
- When it is the correct format, he gives
maxstores the first value as the maximum value. Then he ask again for the next value (goto #2). He continues as longchoosereturns an item itself. Andchoosecontinues as long he gets one frommapand so on …- When
choosedoes not return a value anymore.maxreturns the maximum value he stored so far. Whenchoosedoes not give him a single value. He choose0as the default to return.
So max starts the evaluation. It bubbles back to wrap. So execution is basically
written in reverse. In the case of max all items must be scanned.
There could be multiple different ways to optimze its performance. But, you
probably always will start with replacing/optimizing wrap.
When you give wrap all items at once it internally creates an array and serves
all request from it. This is the operation that blocks. But only once, and at the
very beginning.
Theoretically there is only one way to fix it. You just give it a function that works like a sequence. You can pass it any function that returns another function.
This is how the internals of sequence works. But there are multiple different helpers (Constructors) to help you create such an construct.
Throughout the system, undef is used like an optional. When you return it,
its considered the end of the iterator. Or in some functions returning undef
means = skip this item. So undef values basically disappear as long you use
Seq.
Here a funny part. Seq can return undef. It’s like talking with others.
Inside Seq there is no undef. But it returns it, just like it keeps getting one
from the outside itself.
Like max that can return an undef when the sequence not only contains a single
value. Luckily max can be given a default value that in that case is returned
instead of an undef.
So I am basically fixing “The multi-millard dollar-bug”. Everything as a Perl module to load.
Or at least, an attempt.