Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • The more I read about SAX programming the less I like it. I'd look at turning the element data structures into first class objects:

    sub start_element {
            my $self = shift;
            my $e = ElementFactory->make_from_struct(shift);
            $e->start_with_parser($self);
    }

    And have start_with_parser do the double dispatch trick:

    sub MyElement::docbook::para::start_with_parser {
            my $self = shift;
            my $parser = shift;
            $parser->start_docbook_para($self);
    }

    Of course, this can lead to a proliferation of classes, but careful protocol design can fix that somewhat, for instance, you might be able to have all your docbook elements share a class and do:

    sub MyElement::DocBook::start_with_parser {
            my $self = shift;
            my $parser = shift;
            my $method = "start_docbook_" . $self->element_name;
            $parser->$method($self);
    }

    Combine all this with the State pattern and you have a powerful and flexible system that doesn't suffer from the 'huge case statement' problem. Instead suffers from the 'where does stuff happen? ' problem, but I happen to think that that's an easier problem to deal with because at least the things that happen have sensible names.

    XML Filters might require a little more work, but a simple pass through AUTOLOAD should fix most of your problems (you'd need to map back from your protocol's method names to the appropriate SAX method calls, but unless you're handling some of the more arcane corners of SAX you can probably do that with a simple hash look up based on the first part of the method name -- start_* becomes start_element, end_* becomes end_element etc.)