假设我.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) { ... }
Run Code Online (Sandbox Code Playgroud)
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..."
}
Run Code Online (Sandbox Code Playgroud)
与处于同一级别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...
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切正常。但是,当我尝试从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>
Run Code Online (Sandbox Code Playgroud)
TL; DR我认为这旨在成为一项安全功能。错误消息是LTA。您对问题的评论解释了您需要做什么。这个答案提供了我认为的理由。
我认为也许应该进一步讨论此问题,以期改进错误消息,P6文档p6doc和/或P6编译器中的一个或多个。
我将探索编译器的源代码,以更好地了解正在发生的事情,并计划以后再更新此答案。
首字母缩写词/“ pod”是最初的Perl系列的缩写,代表“普通的旧文档”。在P6中,它已成为Pod(请注意,经过调整的拼写惯例使其与原始P5 Pod / POD有所区别)。Pod与Pod / POD相似,但格式不同。
特别是,它不再是简单或旧的-它是代码。假设它代表“生产最佳文档”或类似的东西。
根据Pod的P6文档,它是:
一种易于使用的标记语言,用于记录Perl模块和程序
Imo它很容易以其源代码形式阅读,并且相当容易编写。(尽管像我们大多数人一样,我已经习惯了使用markdown编写代码……)
但是imo Pod的最显着特征(至少在使用它的情况下)是它的代码。因此,它与代码一样容易使用。也就是说,考虑到恶意代码的问题和保持事物安全的安全性,这不一定完全容易。
以“将使用Pod 6 DSL的Perl 6程序中的文档实际解析为代码的一部分”开头的SO 迈出了一步,以使这一点变得清晰。但是重要的是要意识到它不仅是解析的而且是编译的,并且编译涉及运行编译器,并且在P6中,甚至可能涉及正在编译的程序中运行代码。
这是由于P6语法和语义的性质。
根据维基百科关于标记语言的页面,它们是用于以下内容的系统:
以与文本在语法上可区分的方式注释文档
但是P6语法(和语义)可以由模块动态修改。这具有令人信服的优势1,但是这也意味着必须编译P6代码,以便编译器确定如何解析它。
这包括找出什么是Pod以及如何解析该Pod。另外,Pod可以在编译时调用 P6代码。因此,还必须编译Pod(及其调用的任何代码),并且可能必须运行其中的一些才能弄清楚最终Pod数据是什么。
当然,您可以使用文本查看工具来原位阅读Pod。它经过精心设计,以原始格式非常容易阅读。
但是,如果您使用的p6doc是编译P6代码。(实际上,它p6doc是围绕编译器的非常简单的包装器。)
并且由于P6编译中可以包含运行代码,因此通常必须将与运行代码相同的安全策略应用于p6doc提取P6 Pod。
从安全的角度来看,永远不要运行在您的系统上搜索目录并运行在其中找到的代码的代码,而无需您这么说。
当您编写时p6doc foo/bar,您被认为可以p6doc编译foo/bar并运行编译该代码的任何代码。
但是,use lib当将--doc选项提供给编译器时,会故意忽略编译指示。因此,在其评论中对您的SO的答案。
1这使得P6能够在单个程序中以及作为随时间演变的语言进行无限的突变。与任何图灵完整语言一样,这意味着几乎所有语言都可以做到,P6可以做到。与几乎所有语言不同,如果您这样做并且感觉到它属于该语言而不是作为一个模块,则可以调整P6语言以将其吸收到P6副本中。如果P6人士希望您的语言调整被每个人的P6所吸收,那么您的调整就可以成为该语言未来的一部分。因此,P6使修改P6本身变得容易,并且最大程度地开放了将来的语言改进,并且从根本上消除了可能浪费大量时间和精力的事情之一,即争夺语言中的哪些功能。