【问题标题】:Include Perl class file包含 Perl 类文件
【发布时间】:2011-07-28 23:05:10
【问题描述】:

我有一个 Perl 类文件(包):person.pl

package person;

sub create {
  my $this = {  
    name => undef,
    email => undef
  }

  bless $this;
  return $this;
}  

1;

我需要在另一个文件中使用这个类:test.pl

(注意person.pl和test.pl在同一个目录)

require "person.pl";

$john_doe = person::create();
$john_doe->{name} = "John Doe";
$john_doe->{email} = "johndoe@example.com";

但它没有成功。

我正在使用 XAMPP 来运行 PHP 和 Perl。

我认为使用“require”来获取似乎不太合适 “人”类的代码,但我不知道 如何解决这个问题。请帮忙...

【问题讨论】:

  • 你好 nicola,欢迎来到 Stack Overflow。请花一些时间熟悉editing help 关于代码格式的内容。
  • 您应该以大写字母开头所有包的名称。 Perl 的约定是模块以大写字母开头,语用符号全部小写以一目了然。
  • @shawn:人们喜欢这种约定,但是,我经常做相反的方式。 my_class_name 和 My_Instance_Name。我的约定来自自然的人类语言,比如“software_engineer”是类名,“John Smith”是一个“software_engineer”,看起来更自然。我通常在我的项目中使用这个约定。有点奇怪。 :D

标签: perl oop class include require


【解决方案1】:

首先,您应该将文件命名为 person.pm(对于 Perl 模块)。然后你可以用use函数加载它:

use person;

如果person.pm所在目录不在@INC,可以使用libpragma添加:

use lib 'c:/some_path_to_source_dir';
use person;

其次,Perl 没有构造函数的特殊语法。您将构造函数命名为 create(可以,但不标准),但随后尝试调用不存在的 person::new

如果您打算在 Perl 中进行面向对象编程,那么您真的应该看看 Moose。除此之外,它还会为您创建构造函数。

如果您不想使用 Moose,可以进行以下一些其他改进:

package person;

use strict;   # These 2 lines will help catch a **lot** of mistakes
use warnings; # you might make.  Always use them.

sub new {            # Use the common name
  my $class = shift; # To allow subclassing

  my $this = {  
    name => undef;
    email => undef;
  }

  bless $this, $class; # To allow subclassing
  return $this;
}

然后将构造函数作为类方法调用:

use strict;   # Use strict and warnings in your main program too!
use warnings;
use person;

my $john_doe = person->new();

注意:在 Perl 中使用 $self 而不是 $this 更为常见,但这并不重要。 Perl 的内置对象系统非常小,对您的使用方式几乎没有限制。

【讨论】:

  • 但是“使用人”这一行导致错误。它(perl over apache)说“在@INC blah blah ...中找不到person.pm”,我需要'person.pl'(或'person.pm')与'test.pl'位于同一目录中'
  • 非常感谢代码上的那些cmets,我真的很珍惜这些cmets,但是,主要问题是如何从位于同一目录中的另一个perl文件中加载一个perl源文件跨度>
  • @users:关于动态模块加载,请参阅下面 nicola 的回答(在开发模块源代码时效果最佳)
【解决方案2】:

我找到了解决从同一目录中的另一个 Perl 文件加载 Perl 源文件的问题。通常你会:

use lib "c:/some_dir_path";
use class_name;

当模块的源代码正在开发中时,下面的解决方案会更好,因为它会在 Perl 的缓存中重新加载模块。它确保每次需要时都重新加载类源代码,这意味着每次要包含的文件的源代码的任何更改都会在每次编译或运行时包含该文件时生效:

push (@INC,"c:/some_path_to_source_dir"); #directory contains perl source files

delete @INC{"class1.pl"}; #to reload class1
require "class1.pl";

delete @INC{"class2.pl"}; #to reload class2
require "class2.pl";

delete @INC{"class3.pl"}; #to reload class3
require "class3.pl";

不知道是不是好方法,请指正。

【讨论】:

  • cjm 提供了答案——当然你可以忽略它。
  • 1) 最好使用use lib 'path' 而不是push @INC, 'path'。 2)您不需要“重新加载”您的模块;丢失delete 语句。 3)正常的做法是只对可执行脚本使用.pl;模块(OO 或其他)最好用.pm 命名,这也允许您使用use 而不是require 来加载它们。
  • @reinierpost:是的,这对我理解 perl 中的基本 OOP 有很大帮助
  • @dave: 但是模块文件 (.pm) 是我自己的库并且正在开发中,每次运行主代码文件时我都需要重新加载(在 perl 缓存中刷新)。当然,当我的模块没有更多的修改时,我肯定应该使用 [use lib 'path']。
猜你喜欢
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 2013-04-04
  • 2013-10-28
  • 2010-10-02
  • 2011-02-07
  • 1970-01-01
  • 2019-12-12
相关资源
最近更新 更多