BTW: since you're so kind commenting my article, I'd like to hear your
(and other's) opinion about the other post I wrote, namely the one
about how naturally C<our> fits the existing scheme for "local"
variables under the "natural-language-like-features-in-Perl point of
view"...
Is that the one with Message-ID
<
[email protected]>?
I read that article earlier, but I wasn't sure whether there was anythin
in there that I could comment on
I do think it might show that there is still a bit of a misunderstanding
about what C<my()>, C<local()>, C<our()> and C<use vars> do, and that's
understandable, since they seem to do many similar things.
Maybe a few more explanations, as I see things, could help, in addition
to MJD's "Coping with scoping" article. I'll say much of the same, but
phrased differently.
Perl has two types of variables: There are those that belong to a
package, and those who don't. The ones that don't belong to a package
are _created_ with C<my()>; all others belong to a package. The ones
that don't belong to a package are only available inside of the lexical
scope they are defined in, the others are available globally, which is
why they are also often called global variables.
Perl has two types of scope: lexical scope and "package scope", where
the latter isn't really a scope, more a namespace. Lexical scope is
(mainly) a compile time thing, and is defined by the enclosing block or
file [1]. Package scope is defined by the use of the package keyword.
Variables that don't belong to a package, i.e. the ones created with
c<my()>, are often called lexical variables. This is fine, but it does
introduce a bit of a confusion factor. The term lexical doesn't really
apply to the variable, but only to its name. The name temporary or local
variable would have been a better name[2], since these variables also
cease to exist at the end of the current scope. However, Perl already
had local (see later).
Because lexical scope refers to the name of the variable, and not the
variable itself you can have a lexically scoped package variable with
C<our()>. The variable itself always exists and is accessible, it's just
its short name that is only available in the current lexical scope. It's
as if there is a temporary lexical variable that is an alias for the
package variable[3].
The C<use vars> pragma simply allows you to refer to the named variables
by their short name while inside of the package name space (scope, if
you want).
All of the above work on variable names. Before the days of lexical
variables the mechanism to localise variables was with C<local()>.
However, C<local()> does not really localise a variable, but it
localises a (package) variable value. The current value of the variable
is saved, and restored at the end of the current scope. C<local()> has
no effect on variable names. Nowadays, C<local()> has its main use in
providing temporary values for the builtin variables, and is probably
not the right solution for most other uses.
So, summarising...
C<my()> creates a new non-package variable with lexical scope, and
existence.
C<local()> saves the current value of a package (global) variable and
restores it on leaving the current scope.
C<our()> allows access to a package variable by its short name in the
current lexical scope
C<use vars> allows a variable to be referred to by its short name inside
a package name space.
One of these works with non-package variables, the other three with
globals. Three of these work with (lexical) scopes, and one with package
name spaces. Three of these act on variable names, and one on values
only.
Perfectly clear. So I guess there's no *simple* way, as I naively
thought, to "link" them together by means of an "esoteric common
vector", at least in Perl5. I wonder if in Perl6 they will actually be
different aspects of the same underlying mechanism (I suppose that for
backward compatibility the same apparent behaviour will be
maintainded).
I haven't kept up with Perl 6 too well, but from what I understand a lot
of this is one of the areas where some work will be done.
Perl 6 will depart in many ways from the way things are done in Perl 5.
There is no backward compatibility, except for a Perl5 to Perl 6
translation, which will probably be automatic [4]. Perl 6 is a new language,
and one of the goals of the project is to finally get rid of all the
accumulated backward compatibility mess. Localisation and scope is
actually not that messy, compared to many other things that are being
cleaned up.
Martien
[1] It actually is defined by the location of the declaration up to the
end of the enclosing block or file.
[2] The term private variables, which is also expressed by C<my()> just
doesn't entirely cut it for me, mainly because that expression is
already in heavy use in OO, with a different sort of meaning.
[3] I don't know whether that is how Perl implements it, which is why I
say "as if".
[4] As I said, I don't know too much about it, since I haven't been
following the mailing lists very closely. I just browse them now and
again.