首页 > 解决方案 > 在 @INC 中找不到 MyApp/Schema.pm

问题描述

我正在尝试使用 perl 连接到数据库。我尝试按照本教程https://metacpan.org/pod/release/RIBASUSHI/DBIx-Class-0.082840/lib/DBIx/Class.pod并创建一个名为 MyApp 的简单应用程序,因为他们制作并完全按照他们的方式创建文件确实,但是当我编译 CD.pm 文件时,我收到错误 Can't locate MyApp/Schema.pm in @INC(您可能需要安装 MyApp::Schema 模块)。

该程序看起来像在 Atom 中使用包脚本在 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;

标签: perldbix-class

解决方案


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

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

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

您没有向我们提供您收到的完整错误消息(并且,为了将来参考,这将非常有用),但我怀疑它会继续告诉您当前位于@INC.

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

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

perl -E'say for @INC'

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

在旧版本的 Perl 中,当前目录被自动添加到@INC(你会在我上面提到的程序的输出中看到 '.'),但这被视为安全风险,所以它被删除了(这就是为什么 ikegami 指出你这个答案)。

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

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

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

但是,如果您从程序所在目录以外的其他地方运行程序,那将无法正常工作。所以一个更强大的解决方案是:

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

如果这不起作用,那么可能是您将库放在不同的目录结构中,我们需要更多信息。


推荐阅读