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

Recursive lexically-scoped subroutines #199

Closed
p5pRT opened this issue Jul 16, 1999 · 5 comments
Closed

Recursive lexically-scoped subroutines #199

p5pRT opened this issue Jul 16, 1999 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 16, 1999

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

Searchable as RT1005$

@p5pRT
Copy link
Author

p5pRT commented Jul 16, 1999

From garethr@cre.canon.co.uk

If I run the program

  use strict;
  sub factorial {
  my $fact = sub {
  my ($n) = @​_;
  $n > 0 ? $n * $fact->($n-1) : 1;
  };
  $fact->(@​_);
  }

I get the error

  Global symbol "$fact" requires explicit package name at fact.pl line 9.

The `perlsub' manpage states that

  A "my" declares the listed variables to be confined
  (lexically) to the enclosing block, conditional
  (if/unless/elsif/else), loop
  (for/foreach/while/until/continue), subroutine, eval, or
  do/require/use'd file.

so I think that either Perl's behavour should be changed to match the
documentation, or the documentation should be made clearer.

(I know that I can rewrite `factorial' as

  sub factorial {
  my $fact; $fact = sub {
  my ($n) = @​_;
  $n > 0 ? $n * $fact->($n-1) : 1;
  };
  $fact->(@​_);
  }

in order to get it to work as intended. That's not what this report is
about.)

Perl Info


Site configuration information for perl 5.00502:

Configured by abw at Thu Nov 19 10:50:08 GMT 1998.

Summary of my perl5 (5.0 patchlevel 5 subversion 2) configuration:
  Platform:
    osname=solaris, osvers=2.6, archname=sun4-solaris
    uname='sunos bandanna 5.6 generic_105181-03 sun4u sparc sunw,ultra-1 '
    hint=previous, useposix=true, d_sigaction=define
    usethreads=undef useperlio=undef d_sfio=undef
  Compiler:
    cc='gcc', optimize='-O', gccversion=2.8.0
    cppflags='-I/opt/gnu/include -I/user/perl/build/include'
    ccflags ='-I/opt/gnu/include -I/user/perl/build/include'
    stdchar='unsigned char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    alignbytes=8, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags ='-L/opt/gnu/lib -L/user/perl/build/lib'
    libpth=/opt/gnu/lib /lib /usr/lib /usr/ccs/lib /user/perl/build/lib
    libs=-lsocket -lnsl -lgdbm -ldl -lm -lc -lcrypt -ldb
    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/opt/gnu/lib -L/user/perl/build/lib'

Locally applied patches:
    


@INC for perl 5.00502:
    /apps/perl5/lib/5.00502/sun4-solaris
    /apps/perl5/lib/5.00502
    /apps/perl5/lib/site_perl/5.005/sun4-solaris
    /apps/perl5/lib/site_perl/5.005
    .


Environment for perl 5.00502:
    HOME=/user/garethr
    LANG=C
    LD_LIBRARY_PATH=/usr/dt/lib:/usr/openwin/lib:/apps/X11R5/lib:/usr/lib
    LOGDIR (unset)
    PATH=/usr/dt/bin:/usr/openwin/bin:/bin:/usr/bin:/usr/ucb:/bin:/usr/bin:/cre/bin:/apps/gcc-2.8.0/bin:/apps/frame5/bin:/apps/emacs/bin:/apps/tex/bin:/apps/perl5/bin:/user/web/bin/scripts:/user/web/bin/SunOS-5.6:/apps/gnu/bin:/apps/mysql/bin:/usr/ccs/bin:/apps/X11R5/bin:/usr/openwin/bin
    PERL_BADLANG (unset)
    SHELL=/cre/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jul 19, 2002

@iabyn - Status changed from 'open' to 'resolved'

@p5pRT
Copy link
Author

p5pRT commented Jul 19, 2002

From @iabyn

Date​: Fri, 16 Jul 1999 15​:24​:38 +0100
If I run the program

use strict;
sub factorial \{
  my $fact = sub \{
    my \($n\) = @​\_;
    $n > 0 ? $n \* $fact\->\($n\-1\) : 1;
  \};
  $fact\->\(@​\_\);
\}

I get the error

Global symbol "$fact" requires explicit package name at fact\.pl

line 9.

The `perlsub' manpage states that

A "my" declares the listed variables to be confined
\(lexically\) to the enclosing block\, conditional
\(if/unless/elsif/else\)\, loop
\(for/foreach/while/until/continue\)\, subroutine\, eval\, or
do/require/use'd file\.

so I think that either Perl's behavour should be changed to match the
documentation, or the documentation should be made clearer.

What you are seeing here is a more glorified version of

  my $x = $x;

From perlsub.pod​:

  The declared variable is not introduced (is not visible) until after
  the current statement. Thus,

  my $x = $x;

  can be used to initialize a new $x with the value of the old $x, and
  the expression

  my $x = 123 and $x == 123

  is false unless the old $x happened to have the value C<123>.

So the lexical $fact doesnt come into scope until the end of the
assigment, so the '$fact' seen within the anon sub is the global
$​::fact,
which doesn't exist.

Dave M.

@p5pRT
Copy link
Author

p5pRT commented Jul 19, 2002

From @iabyn

notabug.

@p5pRT
Copy link
Author

p5pRT commented Jul 19, 2002

@iabyn - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Jul 19, 2002
toddr pushed a commit that referenced this issue Oct 19, 2019
warn and test against this published metasploit attack vector.
See GH #199

Conflicts:
	dist/Storable/Storable.pm

TonyC:
 - backported parts of 17a1797 to make it compatible with blead
 - updated MANIFEST
toddr pushed a commit that referenced this issue Oct 19, 2019
warn and test against this published metasploit attack vector.
See GH #199
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