Dynamic variables in perl

I am wondering how I can do in Perl what I usually do in lisp:

(defvar *verbose-level* 0) (defun my-function (... &key ((:verbose-level *verbose-level*) *verbose-level*) ...) ...) 

this means that my-function runs at the current verbosity level, but I can pass it another level that will also affect all its calls:

 (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 

(note that variable bindings are restored when you exit - even abnormal ones - from functions).

How can I do something like this in Perl?

For example, in misc.pm I have our $verbose=0; . How to write a function that binds $verbose to the value of its argument and restores its value upon return?

+7
source share
2 answers

The concept of Perl global variables is pretty similar to special variables in CL.

You can obscure the value of a global variable with local :

 our $var = 1; func("before"); { # a block creates a new scope local $var = 2; func("inside"); } func("after"); sub func { say "@_: $var" } 

Output:

 before: 1 inside: 2 after: 1 

If you are a local value, the new value is displayed in the entire dynamic region, that is, in all called functions. The old value is restored after the lexical region remains in any way (errors, returns, etc.). The tail of calls does not expand the dynamic region, but is calculated as the output of the region.

Note that global variables have a fully qualified name. From another package, you would do something like

 local $Other::Package::var = 3; Other::Package::func("from a package far, far away"); 

This is commonly used to provide configuration of packages with a functional (non-OO) interface. Important examples are Carp as well as Data::Dumper .

+10
source

If you understand correctly, you need to locally override the global variable inside the function.

 package my_package; our $verbose = 0; sub function { my ($arg1, $arg2) = @_; # getting function arguments. local $verbose = $arg1; } 

It will return the previous state of $verbose upon return.

+3
source

All Articles