【问题标题】:Can't locate MyApp/Schema.pm in @INC在 @INC 中找不到 MyApp/Schema.pm
【发布时间】:2023-03-22 11:03:01
【问题描述】:

我正在尝试使用 perl 连接到数据库。我尝试按照本教程https://metacpan.org/pod/release/RIBASUSHI/DBIx-Class-0.082840/lib/DBIx/Class.pod 创建一个名为 MyApp 的简单应用程序,正如他们所做的那样,并完全按照他们所做的方式创建文件,但是当我编译 CD.pm 文件时,我收到错误 Can't locate MyApp/Schema.pm在 @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;

【问题讨论】:

  • 请同时显示您正在运行的程序以及目录列表。使用tree 或类似的东西来制作该列表,这样我们就可以看到在哪里。
  • 我编辑了,希望够用了
  • 为我工作。 › find|grep pm|parallel perl -c./MyApp/Schema.pm syntax OK./MyApp/Schema/Result/CD.pm syntax OK./MyApp/Schema/Result/Artist.pm syntax OK
  • 脚本相对于模块在哪里?你如何告诉 Perl 在哪里寻找模块? Is this relevant?
  • 对不起,我真的不知道如何回答这个问题。我是为网页创建后端的新手,所以我不知道自己在做什么。如果你知道一个很好的教程,我可以学习所有这些,我将不胜感激。

标签: perl dbix-class


【解决方案1】:

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

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

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

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

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

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

perl -E'say for @INC'

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

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

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

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

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

但是,如果您从程序所在目录以外的地方运行程序,这将不起作用。所以更稳健的解决方案是:

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

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

【讨论】:

  • 谢谢,但它不起作用。我用过使用 lib '.'并使用 FindBin '$RealBin';使用库 $RealBin;但我遇到了同样的错误:pastebin.com/PdYyVesc。 (我在 CD.pm 中插入的正是使用 FindBin '$RealBin'; 使用 lib $RealBin; 在文件的顶部,我不知道是否必须用其他东西修改 RealBin)。我在编程方面不是那么新,我在 Perl 之前使用 C++ 和 Java 来解决问题,在 postgresql 中使用 oop 和 datebase,我了解一些导致错误的原因,但我不知道如何解决它。
  • Re "我插入CD.pm",不,在主程序文件中
  • 请勿使用use lib '.';。这是错误的并且存在安全风险。
  • @AlexUnLimited:如果您的问题是 Perl 找不到您的模块,那么很难看出对您的一个模块进行更改会如何改善这种情况。正如我在回答中所说,您需要将代码添加到程序中,而不是模块中。
  • 抱歉,我浪费了你们的时间,我什至在项目中都没有主文件,我正在逐个文件运行只是为了查看是否一切正常,我认为这是问题所在。
猜你喜欢
  • 2020-10-14
  • 1970-01-01
  • 2017-07-13
  • 2021-03-03
  • 2013-10-24
  • 2018-01-11
  • 2020-07-15
  • 2018-11-08
  • 2021-11-17
相关资源
最近更新 更多