jepri has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a webdav server (it works, yay!), but now I'm looking at polishing the edges before I release. A webdav server, for those who aren't up on their jargon, is a HTTP fileserver. One of the things I have observed is that good clients will update the screen as the information flows in (in XML). Now naturally I did the code in good procedural style - one routine gets the list of files, another builds the XML. But this means I build the entire XML document before I send it - leading to the feeling of slowness on the client side.

The meta-code looks like this:

PROPFIND { get_properties_recursive{ while properties get_property_nonrec generate_xml_chunkette loop return xml_chunks } add_xml_header_and_footer return xml_document }

There are obvious things I could do, like pass in the HTTP::Daemon object, and print each chunk as I generate it. But this breaches functional and procedural coding guidlines as I understand them. I will have duplicated server output routines, and my code will not be obvious.

A while ago I heard about something called continuations, which perl doesn't have, but they sound ideal. My current plan is to completely turn my routines inside out (ouch), and hand a code ref to HTTP::Daemon, which it will then call for each chunk of XML (functional style). This will require messy state switches and other yick. Before I do this, would anyone care to recommend a better approach?

____________________
Jeremy
I didn't believe in evil until I dated it.

Replies are listed 'Best First'.
Re: Turning a sub inside out
by shotgunefx (Parson) on Mar 23, 2002 at 04:30 UTC
    Do files and a chunk of XML have a 1-1 mapping?
    You could try using closures like so. (Untested)
    sub make_iterative (\@) { my $count = 0; my $arrayref = shift; return sub { return $count < @$arrayref ? undef : $arrayref->[$count++] +; }; } my @files = get_files(); my $iter = make_iterative(@files); print xml_header(); while (my $el = $iter->()){ print Chunk2XML($el); } print xml_footer();
    Using closures , you can probably fit it into your framework. I just used print because I'm not exactly sure what you're doing codewise.

    -Lee

    "To be civilized is to deny one's nature."
      That's quite cool. The 'print' actually turns into a 'return' because HTTP::Daemon will take a function reference as contents for a HTTP return object, and then keep calling that function ref until it gets an undef. This is a much better form of the solution than the one I had in mind. Thanks!

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.

        You're welcome. The more I use closures, the more I like them. It's a bit to swallow but if you haven't already check out Why I like Functional Programming

        -Lee

        "To be civilized is to deny one's nature."