Perl / perl5

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

Symbol table aliasing not DWIM'ing except under Debugger #3156

Closed p5pRT closed 13 years ago

p5pRT commented 23 years ago

Migrated from rt.perl.org#5249 (status was 'rejected')

Searchable as RT5249$

p5pRT commented 23 years ago

From clintp@geeksalad.org

I have a package with a very\, very long name and many varibles that I want to address within the package. I'd like to alias the entire namespace. I recall doing something like this in older Perls​:

$foo​::bar​::poit​::var="hlaghlag"; *g​::=\%foo​::bar​::poit​::; # Alias g​:: to some long thing. print $g​::var; # Should print hlaghlag

Someone else remembered being able to do this as well\, so I don't think I'm completely senile. It doesn't work now. Explantion​:

Anyways\, in the debugger I can dump g's symbol table and it shows $var is there. And I can print $g​::var at a debugger prompt\, and it's there. Actually trying to use $g​::var in the body of the program yeilds undef.

main​::(foo.pl​:4)​: $foo​::bar​::poit​::var="hlag";   DB\<1> n main​::(foo.pl​:5)​: *g​::=\%foo​::bar​::poit​::;   DB\<1> n main​::(foo.pl​:6)​: print $g​::var\, "\n";   DB\<1> V g $var = 'hlag' # It's there!   DB\<2> print $g​::var hlag # No\, really! It's there!   DB\<3> n   # \<--- hlag should have printed\, It's gone! Debugged program terminated. Use q to quit or R to restart\,   use O inhibit_exit to avoid stopping after program termination\,   h q\, h R or h O to get additional info.

This is under perl 5.6 and perl5.005. At the very least\, it's confusing and not very DWIM'ish.

Perl Info ``` Flags: category=core severity=low This perlbug was built using Perl v5.6.0 - Sat Nov 18 17:53:47 EST 2000 It is being executed now by Perl v5.6.0 - Sat Sep 9 11:57:58 EDT 2000. Site configuration information for perl v5.6.0: Configured by clintp at Sat Sep 9 11:57:58 EDT 2000. Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration: Platform: osname=linux, osvers=2.2.14-5.0smp, archname=i686-linux uname='linux budman 2.2.14-5.0smp #1 smp tue mar 7 21:01:40 est 2000 i686 unknown ' config_args='' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=define use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef Compiler: cc='cc', optimize='-O2', gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) cppflags='-DDEBUGGING' ccflags ='-DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' stdchar='char', d_stdstdio=define, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lndbm -lgdbm -ldb -ldl -lm -lc -lposix -lcrypt libc=/lib/libc-2.1.3.so, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl v5.6.0: /usr/local/lib/perl5/5.6.0/i686-linux /usr/local/lib/perl5/5.6.0 /usr/local/lib/perl5/site_perl/5.6.0/i686-linux /usr/local/lib/perl5/site_perl/5.6.0 /usr/local/lib/perl5/site_perl . Environment for perl v5.6.0: HOME=/home/clintp LANG=en_US LANGUAGE (unset) LD_LIBRARY_PATH=:/usr/local/lib LOGDIR (unset) PATH=/usr/kerberos/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/clintp/bin:. PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 14 years ago

From @chorny

Same result on 5.12.0.

On Thu Jan 18 04​:09​:13 2001\, clintp wrote​:

I have a package with a very\, very long name and many varibles that I want to address within the package. I'd like to alias the entire namespace. I recall doing something like this in older Perls​:

$foo​::bar​::poit​::var="hlaghlag"; *g​::=\%foo​::bar​::poit​::; # Alias g​:: to some long thing. print $g​::var; # Should print hlaghlag

Someone else remembered being able to do this as well\, so I don't think I'm completely senile. It doesn't work now. Explanation​:

Anyways\, in the debugger I can dump g's symbol table and it shows $var is there. And I can print $g​::var at a debugger prompt\, and it's there. Actually trying to use $g​::var in the body of the program yields undef.

main​::(foo.pl​:4)​: $foo​::bar​::poit​::var="hlag"; DB\<1> n main​::(foo.pl​:5)​: *g​::=\%foo​::bar​::poit​::; DB\<1> n main​::(foo.pl​:6)​: print $g​::var\, "\n"; DB\<1> V g $var = 'hlag' # It's there! DB\<2> print $g​::var hlag # No\, really! It's there! DB\<3> n # \<--- hlag should have printed\, It's gone! Debugged program terminated. Use q to quit or R to restart\, use O inhibit_exit to avoid stopping after program termination\, h q\, h R or h O to get additional info.

This is under perl 5.6 and perl5.005. At the very least\, it's confusing and not very DWIM'ish.

-- Alexandr Ciornii\, http​://chorny.net

p5pRT commented 14 years ago

From [Unknown Contact. See original ticket]

Same result on 5.12.0.

On Thu Jan 18 04​:09​:13 2001\, clintp wrote​:

I have a package with a very\, very long name and many varibles that I want to address within the package. I'd like to alias the entire namespace. I recall doing something like this in older Perls​:

$foo​::bar​::poit​::var="hlaghlag"; *g​::=\%foo​::bar​::poit​::; # Alias g​:: to some long thing. print $g​::var; # Should print hlaghlag

Someone else remembered being able to do this as well\, so I don't think I'm completely senile. It doesn't work now. Explanation​:

Anyways\, in the debugger I can dump g's symbol table and it shows $var is there. And I can print $g​::var at a debugger prompt\, and it's there. Actually trying to use $g​::var in the body of the program yields undef.

main​::(foo.pl​:4)​: $foo​::bar​::poit​::var="hlag"; DB\<1> n main​::(foo.pl​:5)​: *g​::=\%foo​::bar​::poit​::; DB\<1> n main​::(foo.pl​:6)​: print $g​::var\, "\n"; DB\<1> V g $var = 'hlag' # It's there! DB\<2> print $g​::var hlag # No\, really! It's there! DB\<3> n # \<--- hlag should have printed\, It's gone! Debugged program terminated. Use q to quit or R to restart\, use O inhibit_exit to avoid stopping after program termination\, h q\, h R or h O to get additional info.

This is under perl 5.6 and perl5.005. At the very least\, it's confusing and not very DWIM'ish.

-- Alexandr Ciornii\, http​://chorny.net

p5pRT commented 14 years ago

From @ikegami

It has nothing to do with the debugger. Anything that delays compilation until after the aliasing is done will suffice.

Apparently\, the "$g​::var" in "print $g​::var" is resolved at compile-time.

----- BEGIN CODE ----- $foo​::bar​::poit​::var = "fbp"; $g​::var = "g"; BEGIN { $h​::var = "h"; }

*g​:: = \%foo​::bar​::poit​::; # Alias g​:: to some long thing. BEGIN { *h​:: = \%foo​::bar​::poit​::; # Alias h​:: to some long thing. }

print "$foo​::bar​::poit​::var\n"; # Prints fbp print "$g​::var\n"; # Prints g print "$h​::var\n"; # Prints fbp

eval ' print "$foo​::bar​::poit​::var\n"; # Prints fbp print "$g​::var\n";; # Prints fbp print "$h​::var\n";; # Prints fbp '; ----- END CODE -----

p5pRT commented 14 years ago

From @ikegami

I suspect that fixing this problem will incur a performance penalty.

There are three workarounds​:

1) Perform the aliasing sooner (e.g. at compile-time).

2) Use symbolic references instead to access the variables (forcing run-time name resolution).

3) Delay the compilation of the variable access (e.g. by using eval).

----- BEGIN CODE ----- $foo​::bar​::poit​::var = "fbp"; $g​::var = "g"; BEGIN { $h​::var = "h"; }

*g​:: = \%foo​::bar​::poit​::; # Alias g​:: to some long thing. BEGIN { *h​:: = \%foo​::bar​::poit​::; # Alias h​:: to some long thing. }

# 1) Do aliasing sooner print "$foo​::bar​::poit​::var\n"; # Prints fbp print "$g​::var\n"; # Prints g print "$h​::var\n"; # Prints fbp

# 2) Lookup variable later. { no strict 'refs'; print "${'foo​::bar​::poit​::var'}\n"; # Prints fbp print "${'g​::var'}\n"; # Prints fbp print "${'h​::var'}\n"; # Prints fbp }

# 3) Compile variable access later eval ' print "$foo​::bar​::poit​::var\n"; # Prints fbp print "$g​::var\n"; # Prints fbp print "$h​::var\n"; # Prints fbp '; ----- END CODE -----

p5pRT commented 13 years ago

From @cpansprout

It’s not possible to fix this\, as it would break compatibility in all sorts of edge cases.

p5pRT commented 13 years ago

@cpansprout - Status changed from 'open' to 'rejected'