Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.88k stars 530 forks source link

subroutine within scope of my variable retains earliest value #5921

Closed p5pRT closed 16 years ago

p5pRT commented 21 years ago

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

Searchable as RT17196$

p5pRT commented 21 years ago

From l.moye@2020speech.com

Created by l.moye@2020speech.com

A "my" variable is declared in subroutine A. Subroutine B is declared within the scope of subroutine A so that it can access this variable. The first time subroutine A is called it all works correctly. The second time subroutine A is called it (A) gets a new\, clean copy of the variable\, but B still carries on using the copy that is got the first time.

Is this a bug or do I have a profound misunderstanding of "my"?

The program below demonstrates the behaviour ****************************************************************************** #!/usr/local/bin/perl

@​l = qw(long green fish); print "in test_my​: "\, \@​l\, "\<"\, join (" "\, @​l)\, ">\n"; &my_sub(@​l);

@​l = qw(mad cows); print "in test_my​: "\, \@​l\, "\<"\, join (" "\, @​l)\, ">\n"; &my_sub(@​l);

sub my_sub {   my @​l;   print "top of my_sub "\, \@​l\, "\<"\, join (" "\, @​l)\, ">\n";   foreach $t (@​_) {   print "in my_sub loop​: $t\n";   &my_sub_sub($t);   }   print "bottom of my_sub "\, \@​l\, "\<"\, join (" "\, @​l)\, ">\n";

  sub my_sub_sub {   print "in my_sub_sub​: @​_\n";   push @​l\, @​_;   print "in my_sub_sub "\, \@​l\, "\<"\, join (" "\, @​l)\, ">\n";   }

} ****************************************************************************** running it produces​: ****************************************************************************** ferlinghetti/perl​: ./test_my_for_mailing in test_my​: ARRAY(0x140011310)\ top of my_sub ARRAY(0x14001a1a0)\<> in my_sub loop​: long in my_sub_sub​: long in my_sub_sub ARRAY(0x14001a1a0)\ in my_sub loop​: green in my_sub_sub​: green in my_sub_sub ARRAY(0x14001a1a0)\ in my_sub loop​: fish in my_sub_sub​: fish in my_sub_sub ARRAY(0x14001a1a0)\ bottom of my_sub ARRAY(0x14001a1a0)\ in test_my​: ARRAY(0x140011310)\ top of my_sub ARRAY(0x14001d4a8)\<> in my_sub loop​: mad in my_sub_sub​: mad in my_sub_sub ARRAY(0x14001a1a0)\ in my_sub loop​: cows in my_sub_sub​: cows in my_sub_sub ARRAY(0x14001a1a0)\ bottom of my_sub ARRAY(0x14001d4a8)\<>

Perl Info ``` Flags: category=core severity=medium This perlbug was built using Perl v5.8.0 - Thu Sep 12 14:05:24 BST 2002 It is being executed now by Perl v5.6.0 - Sat Mar 17 15:48:02 GMT 2001. Site configuration information for perl v5.6.0: Configured by janes at Sat Mar 17 15:48:02 GMT 2001. Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration: Platform: osname=dec_osf, osvers=5.0, archname=alpha-osf1-dec_osf uname='osf1 byron.malvern.2020speech.co.uk v5.0 910 alpha ' config_args='-de' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=define use64bitint=define use64bitall=define uselongdouble=undef usesocks=undef Compiler: cc='cc', optimize='-O4', gccversion= cppflags='-std -ieee -D_INTRINSICS -I/usr/local/include -DLANGUAGE_C' ccflags ='-std -fprm d -ieee -D_INTRINSICS -I/usr/local/include -DLANGUAGE_C' stdchar='unsigned char', d_stdstdio=define, usevfork=false intsize=4, longsize=8, ptrsize=8, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, usemymalloc=y, prototype=define Linker and Libraries: ld='ld', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /var/shlib libs=-lgdbm -ldb -lm -liconv libc=/usr/shlib/libc.so, so=so, useshrplib=true, libperl=libperl.so Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' -Wl,-rpath,/usr/local/lib/perl5/5.6.0/alpha-osf1-dec_osf/CORE' cccdlflags=' ', lddlflags='-shared -expect_unresolved "*" -O4 -msym -std -s -L/usr/local/lib' Locally applied patches: @INC for perl v5.6.0: /home/moye/lib/perl /home/skilling/lib/perl /usr/local/lib/perl5/5.6.0/alpha-osf1-dec_osf /usr/local/lib/perl5/5.6.0 /usr/local/lib/perl5/site_perl/5.6.0/alpha-osf1-dec_osf /usr/local/lib/perl5/site_perl/5.6.0 /usr/local/lib/perl5/site_perl . Environment for perl v5.6.0: HOME=/mnt/ferlinghetti/data/moye LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH=/home/moye/lib/alpha-osf1 LOGDIR (unset) PATH=.:/mnt/ferlinghetti/data/moye/bin/alpha-osf1:/mnt/ferlinghetti/data/moye/bin:/mnt/ferlinghetti/data/moye/lib/perl:/usr/local/SmallEiffel/bin:/home/ponting/lib/sdf/bin:/usr/local/scripts:/usr/local/bin:/usr/bin/X11:/usr/bin:/usr/local/bin/AF:/usr/local/sru/bin:/usr/local/DQS/bin:/usr/local/dat/bin:/usr/local/texmf/bin/alpha-osf1:/usr/local/samba/bin:/sbin:/usr/sbin PERLLIB=/home/moye/lib/perl:/home/skilling/lib/perl PERL_BADLANG (unset) SHELL=/usr/local/bin/bash ```
p5pRT commented 21 years ago

From @rgs

l.moye@​2020speech.com (via RT) wrote​:

A "my" variable is declared in subroutine A. Subroutine B is declared within the scope of subroutine A so that it can access this variable. The first time subroutine A is called it all works correctly. The second time subroutine A is called it (A) gets a new\, clean copy of the variable\, but B still carries on using the copy that is got the first time.

Is this a bug or do I have a profound misunderstanding of "my"?

The program below demonstrates the behaviour

This is not a bug; in fact\, this is documented behaviour. Looks like you have rediscovered closures! (See the perlref manpage for info on closures\, this is likely to be a feature you want to use.)

If you run your example program with -w\, you'll see the warning "Variable "@​l" will not stay shared at - line 22." This warning and its meaning are described in the perldiag manpage.

Thanks for your report anyway. Hope this helps.

p5pRT commented 21 years ago

From l.moye@2020speech.com

Hi Rafael\,

Thanks for your advice\, and sorry for reporting a feature as a bug!

However\, I think there is still a problem for old C-hackers like myself in understanding the documentation.

Had I used the same constructiuon in 'C' it would have worked as expected. All the explanations about closure refer to "anonymous" subroutines​: Perfaq7\, for example​:

Closures are implemented in Perl as anonymous subroutines with lasting references to lexical variables outside their own scopes.

There is nothing to warn the user that closure will occur for a named subroutine (as in my example)\, and that one needs the anonymous subroutine mechanism to enable one subroutine within the scope of another to get useful values of the outer one's "my" variables.

Might I suggest that it would be possible\, perhaps under the explanation of "my"\, to point out that closure occurs in locally declared subroutines\, and to refer the reader to\, not just Perlref (which I found somewhat confusing)\, but also to Perldiag --- "Variable will not stay shared"\, which explains how to cope with it.

Regards\,   Laurie

p5pRT commented 16 years ago

p5p@spam.wizbit.be - Status changed from 'open' to 'resolved'