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

I'm writing code to write data to a well-specified binary format, and also to read it back in. It's pretty simple to recursively serialize everything. Now, I'd also like to make an annotated hex dump of the file. That is, I don't just want to de-serialize the data and call Dumper on the meaningful structure. Rather, I want to show the original bytes and offsets along side the parsed interpretation.

I'm thinking that the code that reads should also do the dumping.

So, how can I do that kind of code reuse?

Normally, a function will take a file handle and consume some bytes and return some object that is the re-constituted meaning of what it read.

My stream isn't necessarily a real file, so I can't assume I can back up; so noting the before position, calling the reader, then rewinding and reading the same bytes to dump in hex is no good. Also, it's recursive and I want to dump each primitive this way, not the entire finished structure.

I really need to remember the offset and bytes content along with the interesting value being returned.

Perhaps have every such reader function return two results as a list, the reconstructed object and the report. When one reader calls subreaders, it adds the breakheads to the report, and catenates (after indenting) the reports from the nested calls.

Or, perhaps have the report attached to the object read and returned, as a property of some kind. A recient discussion convered assigning properties, but it required XS. Either that or always return Perl objects, never simple numbers or strings(yech?).

Or have a global variable for the report. Everyone appends to that as the last step before returning. Is that a double-yech? I think it's doable since I don't have backtracking.

—John

Replies are listed 'Best First'.
Re: Parse and Dump from Same Code
by tall_man (Parson) on Feb 20, 2003 at 04:04 UTC
    Your reader package could have private scoped variables; they wouldn't have to be globals visible from outside. For example:
    package BinaryReader; use strict; { # scope to hide variables my $report; sub getReport { return $report; } # Other reader functions, the only things # that are allowed to update the report. } # end of scope 1;