Perl处理程序有一个很好的介绍吗?

时间:2011-10-21 20:59:17

标签: xml perl handler subroutine

我正在使用Perl mod XML :: SemanticDiff,它可以比较两个XML文档。我想编写自己的自定义处理程序,但是对Perl来说相对较新我不知道如何做到这一点。

我知道处理程序只不过是在发生某些事件时调用的子程序。但是我对这些事件如何调用代码中的方法的实现细节很模糊。

例如,该模块的基本实现从以下内容开始:

my $diff = XML::SemanticDiff->new(keepdata=> 1, keeplinenums => 1, diffhandler => 1);
my @changes = $diff->compare($file1, $file2);

我知道我的自定义处理程序看起来像这样:

sub element_value($self, $element, $to_element_properties, $fromdoc_element_properties) {
  my ($self, @args) = @_;

}

但是,是否需要干预代码来实际调用此子?像,

foreach my $change (@changes) {
  $change->element_value(some_arguements_here);
}

或者在执行$diff->compare($file1, $file2);时自动调用处理程序?

任何指针都会非常感激。

1 个答案:

答案 0 :(得分:2)

是的,引擎会“自动”调用它们。

如果您查看源代码(链接到库的CPAN页面XML::SemanticDiff),您可以看到它是如何轻松完成的:

sub compare {
    # ... some code

       # element value test
        unless ($from_doc->{$element}->{TextChecksum} 
             eq $to_doc->{$element}->{TextChecksum}) {
            push (@warnings, $handler->element_value($element, 
                                                     $to_doc->{$element}, 
                                                     $from_doc->{$element}))
                      if $handler->can('element_value');
        }

有三种处理程序子程序(取决于如何设计使用它们的库):

  1. 预定义名称。这意味着,该库被设计为在特定场景中始终使用名为“XYZ()”的固定名称调用子。对于“使用该名称搜索哪个名称空间”而言,这是非常棘手的?为了解决这个问题,更常见的方法是#2:

  2. 具有预定义方法名称的自定义diff-handler类。从XML::SemanticDiff文档中可以看出,您的库就是这种情况。

    该类通常继承自某些现有的基本处理程序类,其默认处理程序应由您的自定义子类覆盖。或者,它只需要实现一些/所有预定义的方法,但不必继承(后者就是这里的情况)。

    对于XML :: SemanticDiff,通过为自定义处理程序类提供一个对象,告诉模块您的自定义处理程序是什么:

    use XML::SemanticDiff;
    use MyCustomHandlerModule;
    my $handlerObj = MyCustomHandlerModule->new();
    my $diff = XML::SemanticDiff->new({ diffhandler => $handlerObj });
    
  3. 注册处理程序。通常,通过传递子例程引用来处理注册:

    sub myHandler1 { ... };
    sub myHandler2 { ... };
    my $obj = My::Library->new({ Event1_handler => &myHandler1
                               , Event2_handler => &myHandler2 })
    

    第二种方法更灵活,使用频率更高。