John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

In a recursive group of readers that parse out a structure, each needs to know how much more is "allowed" for that sub-reader. Say, the outer function decides the entire block is 20 bytes long, then calls the reader for an inner block that might be coded "loop until I run out of input". Passing it just the handle won't work, as it won't know to stop after 20 bytes total before the outer reader returns.

The obvious method is to pass a length in with the handle everywhere. That's crude, though, so bundling the length and the handle into an object seems better. But in Perl, we can go a step farther: how about a tied handle that knows about the length limit? Is there something like that already out there?

—John

Replies are listed 'Best First'.
Re: Length-limiting handle
by Cabrion (Friar) on Feb 20, 2003 at 00:21 UTC
    A global variable wouldn't be elegant, but it would be fast.

    HEY! Before you hit that vote button, hear me out...

    When factoring recursion out of a routine you MUST use global variables. I've been in those situations where I needed to get rid of recursion because the depth was so great, it was killing performance. Recursion is elegant, but it sucks on performance. Globals are bad in general, but all languages have them, and have them for a reason. Somtimes it's OK to break the rules.

    OK, I've said my peace - now you can vote.

Re: Length-limiting handle
by Zaxo (Archbishop) on Feb 20, 2003 at 00:32 UTC

    How about setting local $/ to a reference to integer before the call, and then read one scalar from the handle?

    { local $/ = \get_next_length(); $foo = <FH>; }

    Are you decoding RIFF files, by chance? You may want to think about unpack's 'C4 V/A*' format ( I think that's correct for RIFF)

    After Compline,
    Zaxo

      Yea, I cound have the "outer" function read the whole thing it's responsible for, then wrap a handle around that scalar to pass to the "inner" code to break that up, etc. until I'm down to primitive types. But, (1) a design goal is not to have size limits and the top level could be very large, and (2) it might be a pipe or other asynchronous source and I can start processing before I can read it all.
Re: Length-limiting handle
by BrowserUk (Patriarch) on Feb 20, 2003 at 05:41 UTC

    If the outer function knows enough to decide that the entire block is 20 bytes, why not have it read the 20 bytes and then pass a string into the subparsers rather than having them read from the handle?

    On your other question about remembering the raw input consumed by each level of your structure. You don't mention what the structure loooks like, but could you use parrellel elements? If its a hash, have a key 'foo' for the parsed data and 'foo_raw' for the input from which it was derived. If the element 'foo' is an array, the 'foo_raw' could just be a scalar containing everything that was consumed to derive the array?

    Speculation.


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.