Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

top-level "my" vars visible in called functions #269

Closed
p5pRT opened this issue Jul 28, 1999 · 3 comments
Closed

top-level "my" vars visible in called functions #269

p5pRT opened this issue Jul 28, 1999 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 28, 1999

Migrated from rt.perl.org#1090 (status was 'resolved')

Searchable as RT1090$

@p5pRT
Copy link
Author

p5pRT commented Jul 28, 1999

From mike@tecc.co.uk

I'm running into a problem which I think is a bug, although it might
be a bug in the documentation rather than the impementation. I'm
seeing both on Solaris (version information automatically included by
"perlbug", I assume), and on a Win-NT perl that I'm using, version
information for which follows​:

<NTVERSION>
bash-2.02$ perl -version

This is perl, version 5.005_03 built for MSWin32-x86-object
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-1999, Larry Wall
 
Binary build 517 provided by ActiveState Tool Corp. http​://www.ActiveState.com
Built 21​:29​:03 May 26 1999

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5.0 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http​://www.perl.com/, the Perl Home Page.

bash-2.02$ perl -V
Summary of my perl5 (5.0 patchlevel 5 subversion 03) configuration​:
  Platform​:
  osname=MSWin32, osvers=4.0, archname=MSWin32-x86-object
  uname=''
  hint=recommended, useposix=true, d_sigaction=undef
  usethreads=undef useperlio=undef d_sfio=undef
  Compiler​:
  cc='cl.exe', optimize='-Od -MD -DNDEBUG -TP -GX', gccversion=
  cppflags='-DWIN32'
  ccflags ='-Od -MD -DNDEBUG -TP -GX -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DE
S_FCRYPT -DPERL_OBJECT'
  stdchar='char', d_stdstdio=define, usevfork=false
  intsize=4, longsize=4, ptrsize=4, doublesize=8
  d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
  alignbytes=8, usemymalloc=n, prototype=define
  Linker and Libraries​:
  ld='link', ldflags ='-nologo -nodefaultlib -release -machine​:x86'
  libpth="C​:\Perl\lib\core" "C​:\Program Files\Mts\Lib"
  libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.
lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock
32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib PerlCRT.lib
  libc=C​:\Perl\lib\CORE\PerlCRT.lib, so=dll, useshrplib=yes, libperl=perlcore.
lib
  Dynamic Linking​:
  dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release -machine​:x86'

Characteristics of this binary (from libperl)​:
  Locally applied patches​:
  ActivePerl Build 517
  Built under MSWin32
  Compiled at May 26 1999 21​:29​:03
  @​INC​:
  C​:/Perl/lib
  C​:/Perl/site/lib
  .
</NTVERSION>

The problem is that "my" variables declared at the top level of my
program (i.e. not in any function) are visible inside functions. For
example, this program​:

  #!/usr/local/bin/perl -w
  use strict;
  my $foo = 2;
  main();
  sub main {
  print("foo is " . $foo . "\n");
  }

Runs perfectly happily, as follows​:

  mike/tmp$ perl -w t2.pl
  foo is 2

Whereas I would expect to see​:

  mike/tmp$ perl -w t2.pl
  Global symbol "foo" requires explicit package name at t2.pl line 6.

Just as if there were no top-level declaration of $foo. I base this
on numerous references (for example, in the "perlsyn" manual) to

  lexically-scoped private variables created with my()

and th even more explicit statement in the "perlfunc" manual that

  A "my" declares the listed variables to be local (lexically)
  to the enclosing block, subroutine, eval, or do/require/use'd
  file.

which says to me that the top-level outside-a-function bit of my
program has its own lexically scoped private space just like each
function. After all, shouldn't the program above behave the same as
this trivial re-ordering?

  #!/usr/local/bin/perl -w
  use strict;
  sub main {
  print("foo is " . $foo . "\n");
  }
  my $foo = 2;
  main();

And indeed this version with an extra layer of function-call​:

  #!/usr/local/bin/perl -w
  use strict;
  main();
  sub main {
  my $foo = 2;
  subfunc();
  }
  sub subfunc {
  print("foo is " . $foo . "\n");
  }

If I've misread the documentation, what _does_ a "my" declaration at
the top-level mean?

Apologies if this is a FAQ -- I have read all the basic FAQs I can
find, which is quite a lot. And yet this seems such a fundamental
point ...

Thanks,

  Mike Taylor
  TECC Ltd.
  mike@​tecc.co.uk
  Tel. +44 181 880 4040


Site configuration information for perl 5.00404​:

Configured by stuart at Wed Jan 14 11​:34​:01 GMT 1998.

Summary of my perl5 (5.0 patchlevel 4 subversion 4) configuration​:
  Platform​:
  osname=solaris, osvers=2.6, archname=sun4-solaris
  uname='sunos handbag.tecc.co.uk 5.6 generic sun4u sparc sunw,ultra-2 '
  hint=recommended, useposix=true, d_sigaction=define
  bincompat3=y useperlio=undef d_sfio=undef
  Compiler​:
  cc='gcc -B/usr/ccs/bin/', optimize='-O', gccversion=2.7.2.3
  cppflags='-I/usr/local/include'
  ccflags ='-I/usr/local/include'
  stdchar='unsigned char', d_stdstdio=define, usevfork=false
  voidflags=15, castflags=0, d_casti32=define, d_castneg=define
  intsize=4, alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries​:
  ld='gcc -B/usr/ccs/bin/', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/ccs/lib
  libs=-lsocket -lnsl -ldl -lm -lc -lcrypt
  libc=/lib/libc.so, so=so
  useshrplib=false, libperl=libperl.a
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
  cccdlflags='-fpic', lddlflags='-G -L/usr/local/lib'

Locally applied patches​:
 


@​INC for perl 5.00404​:
  /usr/local/lib/perl5/sun4-solaris/5.00404
  /usr/local/lib/perl5
  /usr/local/lib/perl5/site_perl/sun4-solaris
  /usr/local/lib/perl5/site_perl
  .


Environment for perl 5.00404​:
  HOME=/export/home/staff/mike
  LANG (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/export/home/staff/mike/bin​:/usr/local/bin​:/usr/bin​:/usr/X/bin​:/usr/ccs/bin.
  PERL_BADLANG (unset)
  SHELL=/usr/local/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jul 28, 1999

From [Unknown Contact. See original ticket]

Date​: Wed, 28 Jul 1999 07​:19​:01 -0400
From​: Chris Nandor <pudge@​pobox.com>

The problem is that "my" variables declared at the top level of my
program (i.e. not in any function) are visible inside functions.

For every function in that file, yes. A lexical scope works that way.
[...]
"the enclosing block" does not end where a new sub-block begins.
[...]
The fact that it is in a subroutine is irrelevant to the rules of scoping.
BLOCKs matter, not subroutines, not packages.

Ah badgers. Of course -- I see it all so clearly now. Thanks for the
crystal exposition, and apologies for wasting your time.

  Mike Taylor
  TECC Ltd.
  mike@​tecc.co.uk
  Tel. +44 181 880 4040

@p5pRT
Copy link
Author

p5pRT commented Jul 28, 1999

From @pudge

At 11.51 +0100 1999.07.28, Mike Taylor wrote​:

The problem is that "my" variables declared at the top level of my
program (i.e. not in any function) are visible inside functions.

For every function in that file, yes. A lexical scope works that way.

my $x = 1;

{
  # $x is visible here
}

sub foo {
  # and here
  for (0..9) {
  # and here too
  }
}

require 'bar.pl'; # $x is not visible in bar.pl

Just as if there were no top-level declaration of $foo. I base this
on numerous references (for example, in the "perlsyn" manual) to

lexically-scoped private variables created with my()

and th even more explicit statement in the "perlfunc" manual that

A "my" declares the listed variables to be local (lexically)
to the enclosing block, subroutine, eval, or do/require/use'd
file.

which says to me that the top-level outside-a-function bit of my
program has its own lexically scoped private space just like each
function.

"the enclosing block" does not end where a new sub-block begins.

After all, shouldn't the program above behave the same as
this trivial re-ordering?

#!/usr/local/bin/perl -w
use strict;
sub main {
print("foo is " . $foo . "\n");
}
my $foo = 2;
main();

No, because scopes are determined at compile time, and $foo is not declared
until after main() is compiled. So you get an error. This is the exact
same scoping as​:

  #!perl -w
  use strict;
  FOO​: for (1) {
  print("foo is " . $foo . "\n");
  }
  my $foo = 2;
  goto FOO if $foo == 2;

The fact that it is in a subroutine is irrelevant to the rules of scoping.
BLOCKs matter, not subroutines, not packages.

And indeed this version with an extra layer of function-call​:

#!/usr/local/bin/perl -w
use strict;
main();
sub main {
my $foo = 2;
subfunc();
}
sub subfunc {
print("foo is " . $foo . "\n");
}

Well, here $foo is never declared in subfunc() or a lexical scope that
contains subfunc().

If I've misread the documentation, what _does_ a "my" declaration at
the top-level mean?

It means the entire file can see it. The file is one big scope. Sometimes
people call these "file-scoped lexicals", as they are lexicals that can be
used anywhere within the file.

--
Chris Nandor mailto​:pudge@​pobox.com http​://pudge.net/
%PGPKey = ('B76E72AD', [1024, '0824090B CE73CA10 1FF77F13 8180B6B6'])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant