我想使用Perl6模块对一些函数进行分组,我经常使用。因为这些函数都是松散耦合的,所以我不喜欢在类中添加它们。
我喜欢use
的想法,您可以选择哪些函数应该导入,但我不喜欢它,导入的函数然后存储在全局命名空间中。
例如,如果我有一个文件my_util.pm6
:
#content of my_util.pm6
unit module my_util;
our sub greet($who) is export(:greet) {
say $who;
}
sub greet2($who) is export(:greet2) {
say $who;
}
sub greet3($who) is export(:greet3) {
say $who;
}
和文件test.p6
:
#!/usr/bin/perl6
#content of test.p6
use v6.c;
use lib '.';
use my_util :greet2;
greet("Bob"); #should not work (because no namespace given) and also doesn't work
greet2("Bob"); #should not work (because no namespace given) but actually works
greet3("Bob"); #should not work (because no namespace given) and also doesn't work
my_util::greet("Alice"); #works, but should not work (because it is not imported)
my_util::greet2("Alice"); #should work, but doesn't work
my_util::greet3("Alice"); #should not work (because it is not imported) and also doesn't work
我想通过my_util::greet()
而不是greet()
来调用所有功能。
greet()
中定义的函数my_util.pm6
非常接近我的要求,但因为它被定义为我们的,所以它总是被导入。我喜欢的是选择应该导入哪些函数的可能性,并且应该可以将它保留在模块定义的命名空间中(即它不会污染全局命名空间)
有谁知道,我怎么能做到这一点?
答案 0 :(得分:7)
词法范围和包符号表是不同的东西。
my
在当前词汇范围中添加了一个符号。
our
在当前词汇范围,和中添加了当前公共符号表的符号封装
use
将请求的符号复制到当前词汇范围。
这被称为"导入"。
::
分隔符执行包查找 - 即foo::greet
在包{{1}的公共符号表中查找符号greet
}}。
这并不涉及任何"导入"。
无论引用它的位置,包的公共符号表都是相同的......没有任何机制可以在不同的范围内显示其中的单个符号。
你可以使冒号成为子程序实际名称的一部分......
foo
...但是你不能再以正常方式调用它了(因为解析器会将其解释为上面的规则4),所以你必须使用笨重的"间接词法查找&# 34;语法,显然不是你想要的:
sub foo::greet($who) is export(:greet) { say "Hello, $who!" }
# This subroutine is now literally called "foo::greet".
所以,你最好的选择是......
foo::greet "Sam"; # Could not find symbol '&greet'
::<&foo::greet>( "Sam" ); # Hello, Sam!
声明子例程,并且可以从our
模块的所有范围访问所有的子事例。
或者:use