Day 6: Think globally, act localizably (File::umask, Locale::Tie, Unix::setuid)

About the series: perlancar's 2014 Advent Calendar: Introduction to a selection of 24 modules which I published in 2014. Table of contents.

Local variables or dynamic scoping is a very nifty feature of Perl that nowadays do not exist in a lot of other languages. It allows you to temporarily set the value of a global variable during a block/scope during runtime, effectively localizing global variables. For example, even though some modules provide configuration settings as global variables, like Data::Dump's $INDENT, you can change the values of these variables without having a global effect by using local:

{
    local $Data::Dump::INDENT = ""; # disable indenting
    $res = Data::Dump::dump(...);
};
# here the value of $Data::Dump::INDENT is restored the original value

So you can see that the automatic restore of variables at the end of scope is the crux of the niceness. Combined with tie, this makes for a nice technique: you can change some global state simply by setting a value to tied variable locally, and that state will be restored automatically at the end of a scope. The first example of this concept that I saw was in File::chdir. I love this technique so much that I created several other modules with the same concept: Locale::Tie (to set locale locally), File::umask (to set umask), and Unix::setuid (to set UID/EUID, like a localizable version of $> and $<). And I'm still looking for more things which I can apply this concept to.

3 Comments

Unix::setuid is a poorly worked out idea. Firstly because it doesn't report errors in any way (despite typically being used in security-critical ways). Secondly because it omits the saved IDs (which are fairly important).

That said, I do like the general idea. Signal::Mask and Signal::Pending do something similar.

Thanks for your input. I'm not sure what you meant by "saved IDs".

You may want to read Setuid Demystified first before writing any kind of setuid wrapper.

Leave a comment

About perlancar

user-pic #perl #indonesia