使用 perl 脚本创建模块

发布于 2024-12-09 14:40:28 字数 839 浏览 1 评论 0原文

可能的重复:
如何创建 Perl 模块?

我的脚本如下一个 xml 文件并创建哈希表。它工作正常,但现在我需要为该代码创建模块,我可以在我的主函数中调用它。在我的主函数文件路径中作为输入,它以哈希形式提供输出。现在我需要为此代码创建模块。

#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML::Reader;

#Reading XML with a pull parser
my $file;
open( $file, 'formal.xml');
my $reader = XML::LibXML::Reader->new( IO => $file ) or die ("unable to open file");
my %nums;
while ($reader->nextElement( 'Data' ) ) {
    my $des = $reader->readOuterXml();
    $reader->nextElement( 'Number' ); 
    my $desnode = $reader->readInnerXml(); 
    $nums{$desnode}= $des;
    print( " NUMBER: $desnode\n" );
    print( " Datainfo: $des\n" );
}

我如何为此代码创建模块?

Possible Duplicate:
How do you create a Perl module?

I have the script that reads an xml file and creates hash table. its working properly but now i need to create module for that code, that i can call in my main function.In my main function file path as input and it gives output as hash. now i need to create module for this code.

#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML::Reader;

#Reading XML with a pull parser
my $file;
open( $file, 'formal.xml');
my $reader = XML::LibXML::Reader->new( IO => $file ) or die ("unable to open file");
my %nums;
while ($reader->nextElement( 'Data' ) ) {
    my $des = $reader->readOuterXml();
    $reader->nextElement( 'Number' ); 
    my $desnode = $reader->readInnerXml(); 
    $nums{$desnode}= $des;
    print( " NUMBER: $desnode\n" );
    print( " Datainfo: $des\n" );
}

how can i create module for this code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月竹挽风 2024-12-16 14:40:28

您需要使用以下代码创建一个扩展名为 .pm 的文件,即“MyModule.pm”:

package MyModule;
use warnings;
use strict;
use XML::LibXML::Reader;

sub mi_function_name {
   #Reading XML with a pull parser
   my $file;
   open( $file, 'formal.xml');
   my $reader = XML::LibXML::Reader->new( IO => $file ) or die ("unable to open file");
   my %nums;
   while ($reader->nextElement( 'Data' ) ) {
      my $des = $reader->readOuterXml();
      $reader->nextElement( 'Number' ); 
      my $desnode = $reader->readInnerXml(); 
      $nums{$desnode}= $des;
      print( " NUMBER: $desnode\n" );
      print( " Datainfo: $des\n" );
   }
}

1; #this is important

在文件中您要使用此模块:

use MyModule;
#...
MyModule::mi_function_name;

这是一个非常简单且基本的模块用法,我推荐更好的讲座教程 (http://www.perlmonks.org/?node_id=102347)以获得更多相关知识

You need to create a file with .pm extension, i.e. "MyModule.pm" with this code:

package MyModule;
use warnings;
use strict;
use XML::LibXML::Reader;

sub mi_function_name {
   #Reading XML with a pull parser
   my $file;
   open( $file, 'formal.xml');
   my $reader = XML::LibXML::Reader->new( IO => $file ) or die ("unable to open file");
   my %nums;
   while ($reader->nextElement( 'Data' ) ) {
      my $des = $reader->readOuterXml();
      $reader->nextElement( 'Number' ); 
      my $desnode = $reader->readInnerXml(); 
      $nums{$desnode}= $des;
      print( " NUMBER: $desnode\n" );
      print( " Datainfo: $des\n" );
   }
}

1; #this is important

And in the file you want to use this module:

use MyModule;
#...
MyModule::mi_function_name;

This is a very simple and basic usage of a module, I recommend the lecture of better tutorials (http://www.perlmonks.org/?node_id=102347) to gain further knowledge on this

鱼忆七猫命九 2024-12-16 14:40:28

查看 Perl 文档。其中包含的教程之一是 perlmod。这提供了很多好的信息。

第一步:将您的程序变成子例程。这样,您就可以将其称为您的代码。我冒昧地这样做了:

#!/usr/bin/perl
use warnings;
use strict;
use Carp;
use XML::LibXML::Reader;

#Reading XML with a pull parser
sub myFunction {
    my $fh = shift; #File Handle (should be opened before calling

    my $reader = XML::LibXML::Reader->new( IO => $fh )
        or croak ("unable to open file");
    my %nums;
    while ($reader->nextElement( 'Data' ) ) {

        my $des = $reader->readOuterXml();

        $reader->nextElement( 'Number' ); 
        my $desnode = $reader->readInnerXml(); 

        $nums{$desnode} = $des;
    }
    return %nums;
}

1;

我做了一个小小的改变。您注意到我不再打开文件了。相反,您将向 MyFunction 子例程传递一个文件句柄。其次,它现在返回包含这些值的哈希,而不是打印 $desnode$des。您不希望子例程输出数据。您希望它们返回数据,并让您的程序决定如何处理这些信息。

我还添加了 use Carp; 行。 Carp 为您提供了两个函数(以及其他一些函数)。一种称为 carp,它是 warning 的替代品,另一种称为 croak,它是 die 的替代品>。这两个函数的作用是报告调用您的函数的用户程序中的行号。这样,用户就不会看到您的模块中的错误,而是看到他们的程序中的错误。

我还在程序底部添加了 1; 行。当模块加载时,如果加载时返回零,则加载失败。因此,您的最后一条语句应该返回一个非零值。 1; 保证了这一点。


现在我们有了一个可以返回的子例程,让我们将您的程序变成一个模块。

要创建模块,您只需在程序顶部说出 package 即可。并且,还要确保最后一条语句以非零值执行。传统做法只是将 1; 作为程序的最后一行。默认情况下,模块名称以 .pm 后缀结尾。模块名称中可以包含用双冒号分隔的名称组件。例如File::Basename。在这种情况下,模块 Basename.pm 位于 @INC 目录列表(默认情况下包括当前目录)。

package 命令只是创建一个单独的命名空间,因此您的包变量和函数不会与使用您的包的程序内的变量和函数的名称发生冲突。

如果您使用面向对象的接口,则没有理由需要导出任何内容。使用您的模块的程序将仅使用面向对象的语法。如果您的模块是基于函数的,您可能希望将函数名称导出到主程序中。

例如,让我们采用File::Basename。该模块将函数 basenamedirname 导入到您的程序中。这允许您执行以下操作:

my $directoryName = dirname $fileName;

而不必执行以下操作:

my $direcotryName = File::Basename::dirname $fileName;

要导出函数,请确保您的模块使用 Exporter 模块,然后设置 变量 @EXPORT_OK@EXPORT 包含您允许在用户程序中导出的函数列表。不同之处在于,如果您说@EXPORT_OK,函数将被导出,但用户必须请求每个函数。如果您使用@EXPORT,所有这些函数将自动导出。

使用您的程序作为基础,您的模块将被称为 Mypackage.pm ,如下所示:

#!/usr/bin/perl

package Mymodule;

use warnings;
use strict;
use Exporter qw(import);
use Carp;
use XML::LibXML::Reader;

our @EXPORT_OK(myFunction);

#Reading XML with a pull parser
sub MyFunction {
    my $fh = shift; #File Handle (should be opened before calling

    my $reader = XML::LibXML::Reader->new( IO => $fh )
        or die ("unable to open file");
    my %nums;
    while ($reader->nextElement( 'Data' ) ) {

        my $des = $reader->readOuterXml();

        $reader->nextElement( 'Number' ); 
        my $desnode = $reader->readInnerXml(); 

        $nums{$desnode}= $des;
    }
    return %nums;
}

1;

最重要的是使用:

  • package Mypackage
  • use Exporter qw (import)
  • our @EXPORT_OK qw(myFunction);

package 函数设置了独立的命名空间,因此您的变量和函数名称不会覆盖 (或被用户覆盖) 程序。

use Exporter 表示您的程序正在使用 Exporter 模块的 import 函数。这允许您将变量和函数导入到用户程序的主命名空间中。这样,用户可以简单地将您的函数引用为 mi_function_name 而不是 Mypackage::my_function_name。理论上,您不必导出任何内容,较新的模块也不需要。这些模块完全是面向对象的,或者只是不想担心命名空间问题。

@EXPORT_OK 数组表示您要导出的内容。这比 @EXPORT 更受欢迎。使用@EXPORT_OK,开发人员必须指定他想要将哪些函数导入到他们的程序中。使用@EXPORT,这是自动完成的。

在使用您的模块的程序中,您需要执行以下操作:

use Mypackage qw(myFunction);

现在,您在程序中所要做的就是

my %returnedHash = myFunction($fh);

现在,Perl 中的事物在不断发展,而我从未接受过任何正式培训。我只是阅读文档并查看各种示例,希望我能正确理解它们。所以,如果有人说我做错了什么,他们可能是对的。我也没有测试任何代码。当我把你的程序变成子程序时,我可能把它搞砸了。

但是,要点应该是正确的:您需要将代码制作成可返回所需信息的可调用子例程。然后,您可以将其变成模块。这并不是那么难做到的。

Take a look at the Perl Documentation. One of the tutorials included is perlmod. This offers a lot of good information.

First step: Make your program into a subroutine. That way, you can call it your code. I've taken the liberty to do that:

#!/usr/bin/perl
use warnings;
use strict;
use Carp;
use XML::LibXML::Reader;

#Reading XML with a pull parser
sub myFunction {
    my $fh = shift; #File Handle (should be opened before calling

    my $reader = XML::LibXML::Reader->new( IO => $fh )
        or croak ("unable to open file");
    my %nums;
    while ($reader->nextElement( 'Data' ) ) {

        my $des = $reader->readOuterXml();

        $reader->nextElement( 'Number' ); 
        my $desnode = $reader->readInnerXml(); 

        $nums{$desnode} = $des;
    }
    return %nums;
}

1;

I've made a wee change. You notice that I no longer open a file. Instead, you'll pass a file handle to your MyFunction subroutine. Second, instead of printing out $desnode and $des, it now returns a hash that has these values in them. You don't want subroutines to output data. You want them to return the data, and let your program decide what to do with the information.

I've also put in a use Carp; line. Carp gives you two functions (as well as a few others). One is called carp which is a replacement for warning, and the other is called croak which is a replacement for die. What these two functions do is report the line number in the user's program which called your function. That way, the user doesn't see the error in your module, but their program.

I've also added the line 1; at the bottom of your program. When a module loads, if it returns a zero on load, the load fails. Thus, your last statement should return a non-zero value. The 1; guarantees it.


Now that we have a subroutine that you can return, let's make your program into a module.

To create a module, all you have to do is say package <moduleName> on top of your program. And, also make sure that the last statement executes with a non-zero value. The tradition is just to put a 1; as the last line of the program. Modules names end with a .pm suffix by default. Modules names can have components in the names separated by double colons. For example File::Basename. In that case, the module, Basename.pm lives in the directory File somewhere in the @INC list of directories (which, by default includes the current directory).

The package command simply creates a separate namespace, so your package variables and functions don't collide with the names of the variables and functions inside the program that uses your package.

If you use an object oriented interface, there's no reason why you need to export anything. The program that uses your module will simply use the object oriented syntax. If your module is function based, you probably want to export your function names into the main program.

For example, let's take File::Basename. This module imports the function basename and dirname into your program. This allows you to do this:

my $directoryName = dirname $fileName;

Instead of having to do this:

my $direcotryName = File::Basename::dirname $fileName;

To export a function, make sure your module uses the Exporter module, and then set the package variable @EXPORT_OK or @EXPORT to contain the list of functions you're allowing to be exported in the user's program. The difference is that if you say @EXPORT_OK, the functions will be exported, but the user must request each one. If you use @EXPORT, all those functions will automatically be exported.

Using your program as a basis, your module will be called Mypackage.pm and look like this:

#!/usr/bin/perl

package Mymodule;

use warnings;
use strict;
use Exporter qw(import);
use Carp;
use XML::LibXML::Reader;

our @EXPORT_OK(myFunction);

#Reading XML with a pull parser
sub MyFunction {
    my $fh = shift; #File Handle (should be opened before calling

    my $reader = XML::LibXML::Reader->new( IO => $fh )
        or die ("unable to open file");
    my %nums;
    while ($reader->nextElement( 'Data' ) ) {

        my $des = $reader->readOuterXml();

        $reader->nextElement( 'Number' ); 
        my $desnode = $reader->readInnerXml(); 

        $nums{$desnode}= $des;
    }
    return %nums;
}

1;

The big thing is the use of:

  • package Mypackage
  • use Exporter qw(import)
  • our @EXPORT_OK qw(myFunction);

The package function sets up an independent name space, so your variables and function names don't override (or get overwritten) by the user's program.

The use Exporter says that your program is using the import function of the Exporter module. This allows you to import variables and functions into the main namespace of the user's program. That way, the user can simply refer to your function as mi_function_name instead of Mypackage::my_function_name. In theory, you don't have to export anything, and newer modules don't. These module are entirely object oriented or just don't want to bother with namespace issues.

The @EXPORT_OK array says what you're exporting. This is preferred over @EXPORT. With @EXPORT_OK, the developer must specify what functions he wants to import into their program. With @EXPORT, this is done automatically.

In the program that uses your module, you'll need to do this:

use Mypackage qw(myFunction);

Now, all you have to do in your program is

my %returnedHash = myFunction($fh);

Now, things are constantly evolving in Perl, and I've never received any formal training. I simply read the documentation and take a look at various examples and hope that I understand them correctly. So, if someone might say that I'm doing something wrong, they're probably correct. I've also didn't test any of the code. I might have screwed something in your program when I turned it into a subroutine.

However, the gist should be correct: You need to make your code into callable subroutines that return the information you need. Then, you can turn it into a module. It's not all that difficult to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文