I’m using the Perl mod XML::SemanticDiff which can compare two XML documents. I want to write my own custom handlers but, being relatively new to Perl I’m at a loss as to how to do this.
I understand that handlers are nothing more than subroutines that get called when certain events take place. But I’m fuzzy on the implementation details on how these events call the methods in my code.
For instance, the basic implementation of this module starts with something like:
my $diff = XML::SemanticDiff->new(keepdata=> 1, keeplinenums => 1, diffhandler => 1);
my @changes = $diff->compare($file1, $file2);
And I know that my custom handlers would look something like this:
sub element_value($self, $element, $to_element_properties, $fromdoc_element_properties) {
my ($self, @args) = @_;
}
But does there need to be intervening code to actually call this sub? Something like,
foreach my $change (@changes) {
$change->element_value(some_arguements_here);
}
Or is the handler automagically called when $diff->compare($file1, $file2); is executed?
Any pointers would be greatly appreciated.
Yes, they are “automagically” called by the engine.
If you look at the source code (linked to from library’s CPAN page
XML::SemanticDiff), you can see how it’s done easily:There are three kinds of handler subroutines (depending on how the library using them is designed):
Predefined name. Meaning, the library is designed to allways call a sub with a fixed name called “XYZ()” in a particular scenario. This is very tricky to get right in terms of “which namespace is searched for the sub with that name”? To address that problem, a more common approach is #2:
A custom diff-handler class with predefined method names. As you can see from
XML::SemanticDiffdocumentation, this is the case with your library.The class is often inheriting from some existing base handler class with default handlers that should be overritten by your custom subclass. Alternately, it merely needs to implement some/all predefined methods but doesn’t have to inherit (the latter is the case here).
In case of XML::SemanticDiff, you tell the module what your custom handler is by giving it an object of the custom handler class:
Registered handlers. Most often, the registration is handled via passing a subroutine reference:
This second method is more flexible and is significantly more frequently used.