in reply to Re: Qualified package variable access
in thread Qualified package variable access

> Lexical variables, i.e. the ones declared with my,

Tangential:

I think we should stop calling my variables "lexical", but rather "private".

It's easier to understand for newbies and less confusing, since "package" vars declared with our are lexically scoped too (well the short non-qualified alias is lexically scoped)

Not a critic at you more a general meditation.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

  • Comment on Re^2: Qualified package variable access ( s/lexical/private/ )

Replies are listed 'Best First'.
Re^3: Qualified package variable access ( s/lexical/private/ )
by jdporter (Paladin) on Dec 18, 2020 at 21:11 UTC
    I think we should stop calling my variables "lexical", but rather "private".

    Whatever the intrinsic merits of calling them "lexical", we certainly should not call them "private" because that has an established, widely understood meaning which is different from what these variables are. I refer to private members of classes in OO languages such as C++ and Java.

    In fact, "lexical" is a very good name for these variables, because the scope (that is, visibility) and lifetime* are both determined by the static lexical context of the code. You can read the code and know exactly where the variable can be seen and used.

    * Of course, both of these things can be "escaped" through references; that's beside the point.

    I reckon we are the only monastery ever to have a dungeon stuffed with 16,000 zombies.
      > we certainly should not call them "private" because that has an established, widely understood meaning which is different from what these variables are. I refer to private members of classes in OO languages such as C++ and Java.

      I'm neither an expert on C++ nor Java.

      Could you please explain the semantic difference to this demo of private methods achieved with my ?

      use strict; use warnings; use 5.10.0; # ======================================== # class definition # ======================================== { package Class; use Carp qw/cluck/; use Data::Dump qw/pp dd/; # ----- constructor sub new { my ($class,@init)=@_; return bless {@init}, $class; } # ----- private methods my $private = sub { my ($self) = @_; cluck "I'm a PRIVATE METHOD of OBJ= " . pp $self ; }; # ----- public methods sub public { my ($self) = @_; cluck "I'm a PUBLIC METHOD of OBJ= " . pp $self ; warn " ... calling private methods...\n"; $self->$private(); } } # ======================================== # demo # ======================================== package main; my $obj = Class->new( ID => 1 ); my $obj2 = Class->new( ID => 2 ); $obj->public; $obj2->public; $obj->private; # fails #$obj->$private; # doesn't compile

      -*- mode: compilation; default-directory: "d:/tmp/pm/" -*- Compilation started at Sat Dec 19 16:53:21 C:/Perl_524/bin\perl.exe -w d:/tmp/pm/private_method.pl I'm a PUBLIC METHOD of OBJ= bless({ ID => 1 }, "Class") at d:/tmp/pm/p +rivate_method.pl line 37. Class::public(Class=HASH(0x1cc1e0)) called at d:/tmp/pm/private_me +thod.pl line 56 ... calling private methods... I'm a PRIVATE METHOD of OBJ= bless({ ID => 1 }, "Class") at d:/tmp/pm/ +private_method.pl line 29. Class::__ANON__(Class=HASH(0x1cc1e0)) called at d:/tmp/pm/private_ +method.pl line 40 Class::public(Class=HASH(0x1cc1e0)) called at d:/tmp/pm/private_me +thod.pl line 56 I'm a PUBLIC METHOD of OBJ= bless({ ID => 2 }, "Class") at d:/tmp/pm/p +rivate_method.pl line 37. Class::public(Class=HASH(0x1cc0d8)) called at d:/tmp/pm/private_me +thod.pl line 57 ... calling private methods... I'm a PRIVATE METHOD of OBJ= bless({ ID => 2 }, "Class") at d:/tmp/pm/ +private_method.pl line 29. Class::__ANON__(Class=HASH(0x1cc0d8)) called at d:/tmp/pm/private_ +method.pl line 40 Class::public(Class=HASH(0x1cc0d8)) called at d:/tmp/pm/private_me +thod.pl line 57 Can't locate object method "private" via package "Class" at d:/tmp/pm/ +private_method.pl line 61. Compilation exited abnormally with code 255 at Sat Dec 19 16:53:22

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Well, one major difference is that that $private is not a member of the class at all, it is a lexical in the same block in which you've defined the subs of the class. And, of course, it's singleton. A class private in C++/Java is not singleton. It could be declared 'static', which would make it singleton; but that still wouldn't be the same as what you've shown. If your $private were truly equivalent, you'd be able to write this:

        use strict; use warnings; { package Class; my $n = 42; sub new { my $pkg = shift; bless {}, $pkg; } sub foo; } sub Class::foo { print "$n\n"; }

        But you can't, of course, because $n is out of scope at that point. It is not a member of the "class".

        I reckon we are the only monastery ever to have a dungeon stuffed with 16,000 zombies.
      > we certainly should not call them "private" because that has an established, widely understood meaning

      The term "private variable" certainly has an established meaning in Perl, it appears many times in the perldocs for my-variables.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re^3: Qualified package variable access ( s/lexical/private/ )
by Anonymous Monk on Dec 18, 2020 at 17:24 UTC

    At the risk of starting a semantic flame war, I have to say that I personally prefer "lexical" because it is a better description of their actual scope -- from the point of specification to the enclosing right curly (or the end of the file).

    If you search "private variable" you get things that are much more widely visible than Perl "my" variables (e.g. Java private attributes). I worry that a newbie coming from such a background may be confused by the use of "private" into misunderstanding the actual scope of the variable.

    Package variables are in fact not lexically scoped, though the ability to access them by their unqualified name can be. Even if you turn on warnings, you can still access them outside the scope of the "our" by fully-qualifying their names. Consider the behavior of the following one-liners:

    perl -E '{ our $foo = 42; } say $foo'

    perl -Mstrict -Mwarnings -E '{ our $foo = 42; } say $main::foo'

    Perl is a large, complex language, and we need to provide ways to help newbies find a way in. My concern with s/lexical/private/g is that it may teach newbies things they have to unlearn to progress.

      I'm aware of all of this, except the Java part.

      But I rather think of something like "private to the scope" is more correct.

      And I doubt that the explanation of term "lexical" is ever properly explained or even intuitive.

      according to Merriam Webster

      Definition of lexical

      1 : of or relating to words or the vocabulary of a language as distinguished from its grammar and construction Our language has many lexical borrowings from other languages.

      2 : of or relating to a lexicon or to lexicography lexical methods aim to list all the relevant forms— A. F. Parker-Rhodes

      But that's not the meaning, IMHO did Larry just adopt it from Lisp.°

      There it's called "lexical" in the meaning of "like you read it".

      perlglossary also mentions "static scoping" in contrast to "dynamic scoping", but the explanation is still confusing

      from perlglossary#lexical...

    • lexical analysis

      Fancy term for tokenizing.

    • lexical scoping

      Looking at your Oxford English Dictionary through a microscope. (Also known as static scoping, because dictionaries don’t change very fast.) Similarly, looking at variables stored in a private dictionary (namespace) for each scope, which are visible only from their point of declaration down to the end of the lexical scope in which they are declared. —Syn. static scoping. —Ant. dynamic scoping.

    • lexical variable

      A variable subject to lexical scoping, declared by my. Often just called a “lexical”. (The our declaration declares a lexically scoped name for a global variable, which is not itself a lexical variable.)

    • But all of this describes only the "scoping" not the nature of my variables - which are hold "in a private dictionary (namespace) for each scope" - sic!

      Maybe clearer from another perspective: local is a way to implement "dynamic scoping", but we wouldn't start calling package vars "dynamic variables", right?

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      °) see CommonLISP#lexical_scope