【问题标题】:Module not found when extracting documentation提取文档时找不到模块
【发布时间】:2019-03-10 02:46:53
【问题描述】:

假设我在Foo 目录中有以下两个.pm6 文件:

  • Vehicle.pm6 - 车辆接口。
=TITLE C<Vehicle> interface

unit role Foo::Vehicle;

#| Get the vehicle to move
method run(--> Nil) { ... }

#| Get fuel into the vehicle
method get-fuel(--> Nil) { ... }
  • Car.pm6 - 一个实现Vehicle 接口的类。
=TITLE C<Car> class

use Foo::Vehicle;
unit class Foo::Car does Foo::Vehicle;

has $!speed = 2;

#| Get the car to move
method run(--> Str) { 
    "{::?CLASS.perl} is moving at {$!speed}km/h."
}

#| Get fuel into the car
method get-fuel(--> Str) { 
    "Getting some fuel..."
}

在与Foo 相同的级别,我有一个main.p6 文件,它实例化Car 类:

#!/usr/bin/env perl6

use lib '.';
use Foo::Car;

my Foo::Car $car .= new;

say $car.run;       #=> Foo::Car is moving at 2km/h.
say $car.get-fuel;  #=> Getting some fuel...

到目前为止,一切正常。但是,当我尝试从Car.pm6(使用p6doc Foo/Car.pm6)获取文档时,出现以下错误:

===SORRY!===
Could not find Foo::Vehicle at line 1 in:
    /home/cosmos/.perl6
    /opt/rakudo/install/share/perl6/site
    /opt/rakudo/install/share/perl6/vendor
    /opt/rakudo/install/share/perl6
    CompUnit::Repository::AbsolutePath<94376788126208>
    CompUnit::Repository::NQP<94376768814296>
    CompUnit::Repository::Perl5<94376768814336>

【问题讨论】:

  • 由于您在脚本中使用use lib '.',我认为您需要将当前目录添加到perl6 搜索路径中,以便p6doc 找到您的模块
  • 设置 perl6 搜索路径到当前目录 do: PERL6LIB=. p6doc Foo/Car.pm6

标签: raku


【解决方案1】:

TL;DR 我认为这是一种安全功能。错误消息是LTA。您问题上的 cmets 解释了您需要做什么:

由于您使用的是 use lib '.'在您的脚本中,我认为您需要将当前目录添加到 perl6 搜索路径,以便 p6doc 找到您的模块 – Håkon Hægland

要将 perl6 搜索路径设置为当前目录,请执行以下操作:PERL6LIB=。 p6doc Foo/Car.pm6 – Valle Lukas

这个答案提供了我认为的基本原理。

我认为也许应该进一步讨论这个问题,以改进错误消息、P6 文档、p6doc 和/或 P6 编译器中的一个或多个。

我将探索编译器的源代码,以更好地了解正在发生的事情,并计划在以后更新此答案。


首字母缩略词/单词“pod”是为最初的 Perl 系列创造的,代表“plain old documentation”。在 P6 中,它变成了 Pod(请注意调整后的拼写约定以将其与原始 P5 pod/POD 区分开来)。 Pod 看起来与 pod/POD 相似,但格式不同。

特别是,它不再是普通的或陈旧的——它是代码。假设它代表“产生最佳文档”或类似的东西。

根据the P6 documentation of Pod 是:

一种易于使用的标记语言,用于记录 Perl 模块和程序

Imo 以源代码形式读取 相当容易,写入 也相当容易。 (虽然像我们大多数人一样,我已经习惯了我用来写这个的降价......)

但imo Pod最显着的特点,至少在使用它的上下文中,是它的代码。所以它就像代码一样容易使用。也就是说,考虑到恶意代码的问题和确保事情安全的安全功能,这并不一定容易。

"The documentation in Perl 6 programs, using the Pod 6 DSL, is actually parsed as part of the code" 开头的 SO 是朝着明确这一点迈出的一步。但重要的是要意识到它不仅仅是解析的,而是编译的,而且编译涉及运行编译器,在 P6 中,甚至可能涉及运行正在编译的程序中的代码。

这是由于 P6 语法和语义的性质造成的。

根据wikipedia's page on markup languages,它们是一个系统:

以在语法上与文本可区分的方式注释文档

但是 P6 语法(和语义)可以由模块动态修改。这有令人信服的好处1,但这也意味着必须编译 P6 代码,以便编译器确定如何解析它。

这包括弄清楚 Pod 是什么以及如何解析该 Pod。此外,Pod 可以在编译时调用 P6 代码。所以 Pod(以及它调用的任何代码)也必须被编译,并且其中一些可能必须运行才能确定最终的 Pod 数据是什么。

您当然可以使用文本查看工具原位阅读 Pod。它经过精心设计,以原始形式相当容易阅读。

但是如果你使用p6doc 你正在编译P6 代码。 (其实是p6doc is a very simple wrapper around the compiler。)

并且因为在 P6 编译中可以包含正在运行的代码,所以通常适用于运行代码的相同安全策略必须适用于使用 p6doc 提取 P6 Pod。

从安全的角度来看,不应该运行在您的系统上搜索目录并运行它在没有您说的情况下找到的代码的代码。

当您编写p6doc foo/bar 时,您被认为是在告诉p6doc 可以编译foo/bar 并运行编译该代码的任何代码。

但是当--doc 选项被提供给编译器时,use lib 编译指示被故意忽略。因此,在上面的 cmets 中您的 SO 的答案。

脚注

1 这使得 P6 能够在单个程序中以及作为一种随时间演变的语言进行无限变异。与任何图灵完备的语言一样,这意味着几乎所有的语言,如果可以做到,P6 可以做到。 几乎所有语言不同,如果您这样做并且觉得它属于该语言而不是作为一个模块,您可以调整 P6 语言以将其吸收到您的 P6 副本中。如果 P6 的人们希望您的语言调整被吸收到每个人的 P6 中,那么您的调整可以成为该语言未来的一部分。因此,P6 使得修改 P6 本身变得容易,并且最大限度地为未来的语言改进开放,并且从本质上消除了可能浪费大量时间和精力的事情之一,即为语言中的哪些特性而争吵。

【讨论】:

  • 好吧,POD 实际上是被解析的,因为它没有像简单的禁区那样通过,里面装满了无用的东西,然后当然是编译了。我很乐意解决您可能提出的文档的任何问题...
  • 非常感谢@raiph 的详细回答。
  • @uzlxxx Yw。需要明确的是,这只是第一部分。就目前而言,它包含猜测(例如,我认为它这样做是作为一项安全功能,但不确定)。我确实知道我的回答的要点是正确的:p6doc 绝对只是perl6 --doc ... 的包装,即运行编译器;编译器必须编译整个源文​​件以提取 Pod;这可能意味着通过搜索路径加载模块;这应该被理解为可能对安全产生影响。我希望今晚能深入了解编译器回购。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
  • 2012-05-09
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多