我想使用 Raku Modules 来对我经常使用的一些功能进行分组。因为这些函数都是松散耦合的,所以我不喜欢将它们添加到一个类中。
我喜欢这个主意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()
only.
功能greet()
定义于my_util.pm6
非常接近我的要求,但因为它被定义为我们的,所以它总是被导入。我喜欢的是选择应该导入哪些函数的可能性,并且应该可以将其保留在模块定义的命名空间中(即它不会污染全局命名空间)
有谁知道,我怎样才能实现这一目标?
为了消除一些潜在的混乱......
词法范围和包符号表是不同的东西。
my添加一个符号到当前词汇范围.
our添加一个符号到当前词汇范围, and to the 公共符号表当前包的。
use将请求的符号复制到当前词汇范围.
这就是所谓的“导入”。
The ::
分隔符进行包查找 - 即foo::greet
查找符号greet
in the 公共符号表包装数量foo
.
这不涉及任何“导入”。
至于你想达到什么目的...
无论从何处引用,包的公共符号表都是相同的...没有机制可以使包中的各个符号在不同范围内可见。
You could使冒号成为子例程实际名称的一部分......
sub foo::greet($who) is export(:greet) { say "Hello, $who!" }
# This subroutine is now literally called "foo::greet".
...但是你不能再以正常的方式调用它(因为解析器会将其解释为上面的规则 4),所以你必须使用笨重的“间接词法查找”语法,这显然不是你想要的想:
foo::greet "Sam"; # Could not find symbol '&greet'
::<&foo::greet>( "Sam" ); # Hello, Sam!
所以,你最好的选择是……
- 声明子例程
our
,并接受这样的事实:all其中可以从所有范围访问use
该模块。
Or:
- 将公共前缀直接添加到子例程名称中,但使用无问题的分隔符(例如破折号),然后正常导入它们:
unit module foo;
sub foo-greet($who) is export(:greet) { ... }
sub foo-greet2($who) is export(:greet2) { ... }
sub foo-greet3($who) is export(:greet3) { ... }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)