Perl6:将函数加载到其他名称空间 [英] Perl6: load functions into other namespace

查看:70
本文介绍了Perl6:将函数加载到其他名称空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常使用Perl6模块来对某些功能进行分组.因为这些功能都是松散耦合的,所以我不喜欢将它们添加到类中.

I want to use Perl6 Modules to group some functions, i often use. Because this functions are all loosely coupled, I don't like to add them in a class.

我喜欢use的想法,您可以在其中选择应导入的函数,但我不喜欢将导入的函数存储在全局名称空间中.

I like the idea of use, where you can select, which functions should be imported, but I don't like it, that the functions, which are imported are then stored in the global namespace.

例如,如果我有文件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()调用所有函数.

I would like to call all functions via my_util::greet() and not via greet() only.

my_util.pm6中定义的函数greet()非常接近我的要求,但是由于它被定义为我们的函数,因此总是被导入.我喜欢的可能性是,选择应该导入的函数,并应该将其保留在模块定义的名称空间中(即,它不会污染全局名称空间)

The function greet() defined in my_util.pm6 comes very close to my requirements, but because it is defined as our, it is always imported. What I like is the possibility, to select which functions should be imported and it should be possible to leave it in the namespace defined by the module (i.e. it doesn't pollute the global namespace)

有人知道我该怎么做到吗?

Does anyone know, how I can achieve this?

推荐答案

要消除一些潜在的混乱...

词法作用域和包符号表是不同的东西.

To clear up some potential confusion...

Lexical scopes and package symbol tables are different things.

  1. my 当前词法添加符号范围.

our 当前词汇表添加符号范围到当前程序包的公共符号表.

our adds a symbol to the current lexical scope, and to the public symbol table of the current package.

use 将请求的符号复制到当前词汇范围.
这就是所谓的导入".

use copies the requested symbols into the current lexical scope.
That's called "importing".

::分隔符进行程序包查找–即foo::greet在软件包foo公共符号表中查找符号greet.
这不涉及任何导入".

The :: separator does a package lookup – i.e. foo::greet looks up the symbol greet in the public symbol table of package foo.
This doesn't involve any "importing".

关于您想要实现的目标...

无论从何处引用程序包,公共符号表都是相同的...没有机制可以使包中的各个符号在不同范围内可见.

As for what you want to achieve...

The public symbol table of a package is the same no matter where it is referenced from... There is no mechanism for making individual symbols in it visible from different scopes.

可以使冒号成为子程序实际名称的一部分...

You could make the colons part of the actual names of the subroutines...

sub foo::greet($who) is export(:greet) { say "Hello, $who!" }
# This subroutine is now literally called "foo::greet".

...但是您就不能再以通常的方式调用它了(因为解析器将按照上面的规则4进行解释),因此您将不得不使用笨拙的间接词法查询"语法,这显然是不是你想要的:

...but then you can't call it in the normal way anymore (because the parser would interpret that as rule 4 above), so you would have to use the clunky "indirect lexical lookup" syntax, which is obviously not what you want:

foo::greet "Sam";          # Could not find symbol '&greet'
::<&foo::greet>( "Sam" );  # Hello, Sam!

所以,您最好的选择是...

So, your best bet would be to either...

  • 使用our声明子例程,并具有以下事实:可以从use模块的所有作用域访问它们的 all .
    或者:
  • 使用子句分隔符(例如破折号)将公共前缀直接添加到子例程名称中,然后正常导入它们:
  • Declare the subroutines with our, and live with the fact that all of them can be accessed from all scopes that use the module.
    Or:
  • Add the common prefix directly to the subroutine names, but using an unproblematic separator (such as the dash), and then import them normally:
unit module foo;
sub foo-greet($who)  is export(:greet)  { ... }
sub foo-greet2($who) is export(:greet2) { ... }
sub foo-greet3($who) is export(:greet3) { ... }

这篇关于Perl6:将函数加载到其他名称空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆