Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the default scoping behavior in Perl the way that it is?

I am learning Perl for school, and currently am learning about the use of the my keyword and about scoping in Perl. (For reference, I was looking at How should I use the "my" keyword in Perl? .) Hopefully this question hasn't already been asked elsewhere, but if not...why is Perl's default behavior the way that it is?

It seems to me that a C-style default scoping makes the most sense...you declare a variable inside a block, the variable exists inside that block, and once you leave that block, that variable is no longer accessible. Why is it that in Perl, to specify this behavior, you must use the my keyword? It seems that limiting a variable's scope to only where it is used would be good standard behavior, and using my all the time seems to be very redundant and like it would contribute to cluttering of code.

Seems a bit like walking in to the grocery store and immediately loudly declaring your preferred brand of such-and-such before continuing with your shopping, just in case anyone around you was curious (which they probably weren't).

(Potential duplicate, this question might get taken down... Why declare Perl variable with "my" at file scope? .)

like image 293
Ryan Blanchard Avatar asked Dec 09 '20 23:12

Ryan Blanchard


2 Answers

If you want lexically-scoped variables, you need some form of declaration.[1]


It seems to me that a C-style default scoping makes the most sense...you declare a variable inside a block, the variable exists inside that block, and once you leave that block, that variable is no longer accessible

That's exactly how it works in Perl. Where one would declare a variable using int i in C, one uses my $i in Perl. Both create a lexically-scoped variable, which is to say a variable which is only visible in the current block and contained blocks. When executing code outside of the block, the variable is not accessible. The scope of variables in Perl is the same as the scope of variables in C.[2]

// Can't use `i` here.           # Can't use `$i` here.
{                                {
   // Can't use `i` here.           # Can't use `$i` here.
   int i = 4;                       my $i = 4;
   printf("%d\n", i);       4       say $i;
   {                                {
      printf("%d\n", i);    4          say $i;
      int i = 5;                       my $i = 5;
      printf("%d\n", i);    5          say $i;
   }                                }
   printf("%d\n", i);       4       say $i;
}                                }
// Can't use `i` here.           # Can't use `$i` here.

  1. Python doesn't have explicit variable declarations, but it also doesn't have lexically-scoped variables; Python variables are function-scoped.

  2. However, the lifetime of variables isn't the same. A scalar can be kept alive past the end of the block in which it resides in Perl, but that's not the case for similar variables in C (variables with "automatic storage duration").

    For example,

    # You can't use `@a` outside of the sub,
    # But you can use the created array anonymously.
    sub f { my @a = qw( abc def ); return \@a; }
    

    In that sense, my $x is more akin to a dynamically allocated struct.

like image 86
ikegami Avatar answered Oct 04 '22 06:10

ikegami


Because that's how Larry Wall did it in 1987 and Perl 5 remains backwards compatible with that decision. Lexical variables were not introduced until Perl 5 in 1994 and by then there was quite a large install base of Perl 4 programs.

I'll speculate why. Perl was not conceived as an application language, it became one. Perl 1 was written in 1987 as a more powerful alternative to sed, awk, and Bourne shell.

If you have a problem that would ordinarily use sed or awk or sh, but it exceeds their capabilities or must run a little faster, and you don’t want to write the silly thing in C, then perl may be for you.

From the Perl 1.0 manual.

sed and awk programs are usually just one line. And in shell variables are global. Given the purpose of Perl 1, that was just fine.

Accepted software engineering standards have changed a lot in the last few couple decades. Back when systems were smaller and simpler, global variables were more acceptable. As complexity has grown, global variables are increasingly a hazard.

like image 23
Schwern Avatar answered Oct 04 '22 05:10

Schwern