Is it right to get and especially set global variables of the Perl module directly?

I was wondering what is the best way to use Perl to get or, more importantly, configure a global variable of some module by directly accessing $Module::varName if the module did not provide the getter / setter method for it.

The reason I smell bad is the fact that this is a kind of bypass of the capsules. Just because I can do this in Perl, I'm not quite sure what I should (assuming there is actually an alternative, for example, adding a getter / setter to the module).

+7
coding-style encapsulation perl perl-module
source share
4 answers

It does not break encapsulation if the variable is part of the public API. (If this is not another matter.)

I think direct access is preferable because it allows you to use dynamic scaling:

 local $Module::varName = 42; 

This makes conflicts with other code using Module less likely.

+8
source share

Global modular variables were in vogue in the past, but were considered "bad form" as an interface in Modern Perl. It is important to recognize that Perl is now 22-23 years old, and its styles and practices have changed. :) Please note that there are times when it still fits, because there are some very nice features that come with the package variables. As usual, experience and practice show how good a solution can be.

To understand how best to use package variables, you really need to understand how local works. Check out local perldoc help . Local allows you to take a package variable, like (example) $My::Variable in a My package, and create a dynamically limited version of This. Usually, if you change $My::Variable into place, it will affect your entire program and will be saved. For small programs, this may not be a big problem. For large, this can have disastrous side effects. local allows you to temporarily change this variable, limited to your current scope.

Here's how it works:

 use 5.012; use warnings; package My; our $Variable = 5; package main; say $My::Variable; # prints 5 $My::Variable = 7; say $My::Variable; # prints 7 { # create a new lexical scope local $My::Variable = 10; # create a new dynamic scope for $My::Variable # that will persist to the end of the lexical scope say $My::Variable; # prints 10 } say $My::Variable; # end of the lexical scope for the localized # $My::Variable, so prints 7 again 

Effectively, it allows you to safely use batch variables. Unfortunately, not everyone knows about local ones, so they often compress a global variable. It is always helpful to document good usage (e.g. local ).

A getter / setter with proper encapsulation of objects prevents this a lot, but not always. To make it work like a local variable does, you will need to do a lot of extra work. The best part is that you can localize the package variable, so that you can make temporary changes very easily, say, for a debug variable. Usually you need to make a template like:

 { my $current_variable My::get_variable(); $My::set_variable($new_value); # Do code work $My::set_variable($current_variable); } 

With local, it becomes:

 { local $My::Variable = $new_value; # do code work } 

(By the way, I would like you to be able to do this with lexical variables, for the same reason ... but you cannot.) So, for some things, package variables may make sense. It depends on how you want to use it. Such things as

  • Debugging variables
  • A global configuration that should not / should not change frequently

However, if something needs to be changed on a regular basis, for example

  • Regularly used variables (see the awful interface for File::Find )
  • Temporary configuration
  • "Object" Variables

Basically, everything that needs to be changed more than once, or in rare situations, or otherwise needs to be encapsulated in the generated object, then I would avoid the package variable.

+2
source share

If the module does not provide an accessory, create it, use it and send it to the patch.

+1
source share

Is input sanitation / error processing a treatment of what encapsulation is?

If this is not necessary, then one could object to the implementation of getters and setters, which would then look somewhat silly, like sub set_variable { $variable = shift; } sub set_variable { $variable = shift; } .

Keep in mind, it’s easier for you to use set_variable(42) than Michael suggests.

-2
source share

All Articles