使用模块加载一组相关功能 [英] Using modules to load a group of related functions

查看:38
本文介绍了使用模块加载一组相关功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用Raku Modules来分组一些我经常使用的功能.因为这些函数都是松散耦合的,所以我不喜欢把它们添加到一个类中.

I want to use Raku Modules to group some functions, I often use. Because these 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:

For example if I have a file 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当前词法范围到当前包的公共符号表.

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 声明子程序,并接受这样一个事实:all 可以从use 模块的所有范围访问.
    或者:
  • 将公共前缀直接添加到子程序名称中,但使用没有问题的分隔符(例如破折号),然后正常导入:
  • 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) { ... }

这篇关于使用模块加载一组相关功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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