On Tue, May 15, 2018 at 06:02:40PM +0100, Andrew Solomon wrote:
> $| is a global* variable so you use local to isolate this
> change to only where you need it.

Just to expand on this idea, this is called "dynamic scope"[1]
(as opposed to global or local scope). Effectively a new scope is
allocated when you use local and all code within the current *and
nested* scopes will see the new value, but as soon as you leave
the current scope (by any means, including an "exception"!) it
will revert back to its previous value.

[1] https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scoping

To illustrate it's best to show nested calls:

#!/usr/bin/env perl

use feature 'say';
use strict;
use warnings;

our $foo = 1;

f2();    # => 1
f1();     # ...
p(); # => 1

sub p {
    say $foo;
}

sub f1 {
    local $foo = 2;

    p();   # => 2
    f2();  # => 2
}

sub f2 {
    p();
}

__END__

Compare that to a lexical variable. You could have defined a
lexical variable $foo in `f1`, and within `f1` it would have
evaluated `$foo` as 2, but within `f2` inside of `f1` it would
have still seen the package variable at 1.

And compare that to the package variable itself. If you
reassigned the package variable it would remain at 2 forever
until some other piece of the program modifed it again.

Dynamic scope gives you an isolated, temporary modification of
some "global"/package scope variable without affecting other
parts of the program.

To achieve this in other languages you often have to copy the
value, and execute the action in the equivalent of a
try...finally construct to restore the original value before
leaving the scope, which is far more error-prone and far more
difficult to read.

As mentioned, unless you limit the scope of `local` there isn't
much point. If you use local from the package scope of `main`
you're effectively changing it for the entire program. As a
result, you'll often see it used withn a do {} statement in such
a context to allocate a limited scope for it:

    my $contents = do {
        local $/ = undef; # Temporarily set read record separator
        <$file_handle>;   # to undefined to slurp the whole file.
    };

Regards,


-- 
Brandon McCaig <bamcc...@gmail.com> <bamb...@castopulence.org>
Castopulence Software <https://www.castopulence.org/>
Blog <http://www.bambams.ca/>
perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }.
q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.};
tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'

Attachment: signature.asc
Description: PGP signature

Reply via email to