在@INC中找不到MyApp / Schema.pm

时间:2019-07-23 11:11:51

标签: perl dbix-class

我正在尝试使用perl连接到数据库。我尝试按照本教程https://metacpan.org/pod/release/RIBASUSHI/DBIx-Class-0.082840/lib/DBIx/Class.pod的操作,创建了一个名为MyApp的简单应用,并按原样创建了文件,但是在编译CD.pm文件时出现错误:找不到MyApp / Schema @INC中的.pm(您可能需要安装MyApp :: Schema模块)。

程序看起来像Atom中那样,使用Script包在ubuntu上运行代码:

MyApp---
     |  |
     |  Schema--
     |         |
     |          Result-----
     |                |    |
     |       Artist.pm     CD.pm
     |
Schema.pm


#Schema.pm
package MyApp::Schema;
use base qw/DBIx::Class::Schema/;

__PACKAGE__->load_namespaces();

1;
#CD.pm
package MyApp::Schema::Result::CD;
use base qw/DBIx::Class::Core/;

__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
__PACKAGE__->table('cd');
__PACKAGE__->add_columns(qw/ cdid artistid title year /);
__PACKAGE__->set_primary_key('cdid');
__PACKAGE__->belongs_to(artist => 'MyApp::Schema::Result::Artist', 'artistid');

 1;
#Artist.pm
package MyApp::Schema::Result::Artist;
use base qw/DBIx::Class::Core/;

__PACKAGE__->table('artist');
__PACKAGE__->add_columns(qw/ artistid name /);
__PACKAGE__->set_primary_key('artistid');
__PACKAGE__->has_many(cds => 'MyApp::Schema::Result::CD', 'artistid');

1;

1 个答案:

答案 0 :(得分:3)

  

我是为网页创建后端的新手,所以我不知道自己在做什么

如果是这样的话,那么我真的认为构建一个使用DBIx :: Class的应用程序对于您的第一次尝试有点麻烦。我建议您花一些时间先熟悉一下用Perl编写命令行程序。

但这可能是不可能的。在这种情况下,请继续阅读...

您还没有向我们提供您所得到的完整错误消息(并且,对于将来的参考,这将非常有用),但是我怀疑它会继续告诉您当前位于的目录列表@INC

当Perl加载模块时,它需要知道在哪里可以找到包含该模块的文件。它通过使用称为@INC的特殊数组变量来实现。 @INC包含Perl应该搜索以找到模块代码的所有目录的列表。设置Perl安装时,有许多目录可以“嵌入”其中,但是有多种方法可以添加到该列表中。

您的错误消息将为您提供@INC中的当前目录列表,但是您也可以从以下简单的命令行Perl程序中获取它:

perl -E'say for @INC'

该列表包含我之前提到的“烘焙”目录。这些是Perl希望在其中找到模块的标准目录。但是,属于应用程序的模块(MyApp::Schema模块)未存储在这些目录中。它们与您的程序位于同一目录树中。

在旧版本的Perl中,当前目录已自动添加到@INC(您会在上面提到的程序的输出中看到“。”),但这被视为存在安全风险,因此被删除(这就是池上将您指向this answer的原因。)

因此,我们需要将当前目录添加到@INC。我们可以使用lib杂注将目录添加到@INC。最简单的选择是将此行添加到程序顶部附近(在use MyApp::Schema行之前):

[注意::对于“很好的原因”,当前目录已从默认的@INC中删除。下面的代码行只是删除了Perl开发团队所做的出色工作。正如我在上面所说的,这当然是最简单的选择,但这也是一个非常愚蠢的想法。]

# Don't do this. Use the next code block instead.
use lib '.';

但是,如果您从程序所在的目录之外的其他地方运行程序,那将行不通。因此,更可靠的解决方案是:

use FindBin '$RealBin';
use lib $RealBin;

如果这不起作用,则可能是您已将库置于其他目录结构中,我们将需要更多信息。