我試過遵循其他一些例子,并有類似的東西:
{
package Foo::Bar;
}
{
package Foo::Baz;
use Foo::Bar;
}
use Foo::Baz;
# some more code
# Fails with: Can't locate Foo/Bar.pm in @INC
我的真實示例是我想捆綁/連接https://github.com/TeX-Live/texlive-source/blob/trunk/texk/texlive/linked_scripts/texlive/fmtutil.pl及其依賴項https ://github.com/TeX-Live/installer/blob/master/tlpkg/TeXLive/TLConfig.pm和https://github.com/TeX-Live/installer/blob/master/tlpkg/TeXLive/TLUtils.pm成單個檔案。
謝謝!
uj5u.com熱心網友回復:
問題是 Perl 不知道模塊已經加載,因為您沒有忠實地復制加載程序。具體來說,您沒有修改%INC.
在編譯時未加載模塊也可能會出現問題。這可以使用BEGIN塊來實作。
要行內模塊,請將以下內容添加到腳本的開頭:
BEGIN {
# Insert module here.
$INC{ ( __PACKAGE__ =~ s{::}{/}rg ) . ".pm" } = 1;
}
所以如果你有
# script.pl
use strict;
use Foo::Baz;
# ...
# Foo/Bar.pm
package Foo::Bar;
use strict;
# ...
1;
# Foo/Baz.pm
package Foo::Baz;
use strict;
use Foo::Bar;
# ...
1;
你最終會得到
BEGIN {
# Foo/Bar.pm
package Foo::Bar;
use strict;
# ...
$INC{ ( __PACKAGE__ =~ s{::}{/}rg ) . ".pm" } = 1;
}
BEGIN {
# Foo/Baz.pm
package Foo::Baz;
use strict;
use Foo::Bar;
# ...
$INC{ ( __PACKAGE__ =~ s{::}{/}rg ) . ".pm" } = 1;
}
# script.pl
use strict;
use Foo::Baz;
# ...
請注意,上述內容并不 100% 等同于行內模塊。例如,相當于
use 5.012;
use open ":std", ":encoding(UTF-8)";
use Some::Module;
實際上會
# Non-lexical effects
BEGIN {
require 5.012;
binmode(STDIN, ":encoding(UTF-8)");
binmode(STDOUT, ":encoding(UTF-8)");
binmode(STDERR, ":encoding(UTF-8)");
}
BEGIN {
package Some::Module;
...
$INC{"Some/Module.pm"} = 1;
}
# Lexical effects
use 5.012;
use open ":encoding(UTF-8)";
要正確行內模塊,最好使用@INC鉤子。使用第一種方法中的檔案,最終會得到
BEGIN {
my %modules = (
"Foo/Bar.pm" => <<'__EOI__',
# Foo/Bar.pm
package Foo::Bar;
use strict;
# ...
1;
__EOI__
"Foo/Baz.pm" => <<'__EOI__',
# Foo/Baz.pm
package Foo::Baz;
use strict;
use Foo::Bar;
# ...
1;
__EOI__
);
unshift @INC, sub {
my $module = $modules{$_[1]}
or return;
return \$module;
};
}
# script.pl
use strict;
use Foo::Baz;
# ...
App::FatPacker可用于以這種方式行內模塊。
The line numbers in warnings and errors will be the line numbers of the original file. a #line directive added to the inlined module would adjust that.
uj5u.com熱心網友回復:
你沒有use在同一個檔案中定義包。它們已經通過加載檔案進行編譯和決議。例子:
{
package Foo::Bar;
sub bar { print "bar\n" }
}
{
package Foo::Baz;
sub baz {
Foo::Bar::bar();
print "baz\n"
}
}
use strict;
use warnings;
Foo::Baz::baz();
輸出:
bar
baz
該use陳述句用于從@INC.
uj5u.com熱心網友回復:
在正常設定中,use Module呼叫有兩個作業:
- 找到源檔案
Module.pm并像編譯階段require呼叫一樣決議它,然后 - 呼叫
Module::import函式
通過行內你的模塊,你不需要做第一份作業。模塊的函式和設定代碼已經在正確的命名空間中定義。
呼叫import第二步可能需要也可能不需要,或者可能需要多次呼叫,這取決于可以匯出哪些函式以及您希望在哪些命名空間中使用它們。
package Foo::Bar;
use parent 'Exporter';
@Foo::Bar::EXPORT_OK = qw(bar1 bar2);
sub bar1 { 47 }
sub bar2 { 73 }
package Foo::Baz;
@Foo::Baz::EXPORT_OK = "baz1";
use parent 'Exporter';
Foo::Bar->import("bar1");
sub baz1 { return bar1() 42 }
package main;
Foo::Bar->import("bar2");
Foo::Baz->import("baz1");
sub main2 { return bar2() baz1() 19 }
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316267.html
上一篇:如何使用Perl的Text::Aspell對文本進行拼寫檢查?
下一篇:從后往上讀取日志檔案-perl
