我想知道如何在Perl中做我在lisp中常做的事情:
(defvar *verbose-level* 0)
(defun my-function (... &key ((:verbose-level *verbose-level*) *verbose-level*) ...) ...)
这意味着my-function
以当前的详细程度运行,但我可以将其传递给不同的级别,这也将影响其所有调用:
(defun f1 (&key ((:verbose-level *verbose-level*) *verbose-level*))
(format t "~S: ~S=~S~%" 'f1 '*verbose-level* *verbose-level*)
(f2 :verbose-level 1)
(format t "~S: ~S=~S~%" 'f1 '*verbose-level* *verbose-level*)
(f2 :verbose-level (1+ *verbose-level*))
(format t "~S: ~S=~S~%" 'f1 '*verbose-level* *verbose-level*))
(defun f2 (&key ((:verbose-level *verbose-level*) *verbose-level*))
(format t "~S: ~S=~S~%" 'f2 '*verbose-level* *verbose-level*))
[17]> (f1)
F1: *VERBOSE-LEVEL*=0
F2: *VERBOSE-LEVEL*=1
F1: *VERBOSE-LEVEL*=0
F2: *VERBOSE-LEVEL*=1
F1: *VERBOSE-LEVEL*=0
NIL
[18]> (f1 :verbose-level 4)
F1: *VERBOSE-LEVEL*=4
F2: *VERBOSE-LEVEL*=1
F1: *VERBOSE-LEVEL*=4
F2: *VERBOSE-LEVEL*=5
F1: *VERBOSE-LEVEL*=4
(请注意,变量绑定会在退出时恢复 - 甚至是异常 - 来自函数)。
我怎样才能在Perl中做类似的事情?
例如,在misc.pm
中,我有our $verbose=0;
。
如何编写一个将$verbose
绑定到其参数值并在返回时恢复其值的函数?
答案 0 :(得分:10)
Perl的全局变量概念与CL中的特殊变量非常相似。
您可以使用local
“隐藏”全局变量的值:
our $var = 1;
func("before");
{
# a block creates a new scope
local $var = 2;
func("inside");
}
func("after");
sub func { say "@_: $var" }
输出:
before: 1
inside: 2
after: 1
如果local
是一个值,则新值在整个动态范围内都可见,即在所有被调用的函数中都可见。一旦通过任何方式(错误,返回等)留下词法范围,旧值就会恢复。尾调用不会扩展动态范围,而是计为范围退出。
请注意,全局变量具有完全限定名称。从不同的包中,您可以执行类似
的操作local $Other::Package::var = 3;
Other::Package::func("from a package far, far away");
这通常用于为具有功能(非OO)接口的包提供配置。重要的例子是
Carp
和
Data::Dumper
答案 1 :(得分:3)
如果我理解正确,您需要在函数内局部覆盖全局变量。
package my_package;
our $verbose = 0;
sub function {
my ($arg1, $arg2) = @_; # getting function arguments.
local $verbose = $arg1;
}
它会在返回时恢复$verbose
的旧状态。