假设我在目录.pm6
中有以下两个Foo
文件:
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
接口(interface)的类。 =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>
最佳答案
TL; DR 我认为这旨在成为一种安全功能。错误消息是LTA。您对问题的评论解释了您需要做的事情:
这个答案提供了我认为的理由。
我认为也许应该进一步讨论该问题,以期改善错误消息,P6文档,p6doc
和/或P6编译器中的一个或多个错误消息。
我将探索编译器的源代码,以更好地了解正在发生的事情,并计划以后再更新此答案。
首字母缩写词/“pod”是最初的Perl系列的缩写,代表“普通的旧文档”。在P6中,它已成为Pod(请注意,经过调整的拼写约定使其与原始P5 Pod/POD有所区别)。 Pod外观类似于pod/POD,但格式不同。
特别是,它不再是简单或旧的-它是代码。假设它代表“生产最佳文档”或类似的东西。
每the P6 documentation of Pod是:
Imo它很容易以其源代码形式阅读,并且相当容易编写。 (尽管像我们大多数人一样,我已经习惯了使用markdown编写此代码...)
但是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
并运行属于该代码一部分的任何代码。
但是,将use lib
选项提供给编译器时,会故意忽略--doc
编译指示。因此,在其评论中对您的SO的答案。
脚注
1这使得P6能够在单个程序中以及作为随时间演变的语言进行无限的突变。与任何图灵完整语言一样,这意味着几乎所有语言都可以做到,P6可以做到。与几乎所有语言不同,如果您这样做并且感觉到它属于该语言而不是作为一个模块,则可以调整P6语言以将其吸收到P6副本中。如果P6人士希望您的语言调整被每个人的P6所吸收,那么您的调整就可以成为该语言 future 的一部分。因此,P6使得修改P6本身变得容易,并且最大程度地开放了将来的语言改进,并且从根本上消除了可能浪费大量时间和精力的事情之一,即争夺该语言中的哪些功能。
关于raku - 提取文档时找不到模块,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55083989/