On 06/05/2011 01:21, Mike McClain wrote: > > Here's a simple example that illustrates the problem I've run into: > > perl -le' > show(); > { my @fibs = (0,1,1); my ($x, $y) = (1,2); > sub show > { print "x=$x\ty=$y\t\$#fibs=$#fibs\tfibs=@fibs\tscalar \@fibs = ", > scalar @fibs; > }; > $fibs[$#fibs+1] = 2; > } > show(); > ' > x= y= $#fibs=-1 fibs= scalar @fibs = 0 > x=1 y=2 $#fibs=3 fibs=0 1 1 2 scalar @fibs = 4 > > The first time show() runs it acts as if it can't see $x, $y or @fibs. > The second time it does yet the interpreter had to have seen $x, $y > and @fibs in order to find the definition of show(). > > I've grown accustomed to writing 'C' style code in Perl with main > before the subs rather than shell or Forth style but here it seems to > fail. > > I know I can use memoize but where I ran across this problem was > in trying to write a fibonacci routine that would take advantage of > any previously calculated values rather than starting at 1 again as > a memoized function would be required to do. > > I've searched 'Programming|Learning|Intermediate Perl' books as > well as Google, PerlMonks and this list but haven't found an explanation > for what I'm seeing and explanation is what I'm interested in though lacking > that a work-around would help. BTW, this is Perl 5.8.8.
Hey Mike As Uri says, initialising variables at the point of declaration is done at run time. This is from 'Programming Perl', in the section 4.8.2 - 'Lexically Scoped Variables: my' > A statement sequence may contain declarations of lexically scoped variables. > Such declarations tend to be placed at the front of the statement sequence, > but > this is not a requirement. In addition to declaring variable names at compile > time, the declarations act like ordinary run-time statements: each of them is > elaborated within the sequence of statements as if it were an ordinary > statement > without the modifier. This could be solved with a BEGIN block, but an INIT block is more appropriate as it ensures that compilation is complete and all 'use' statements have been executed. Like this: use strict; use warnings; show(); INIT { my @fibs = (0,1,1); my ($x, $y) = (1,2); sub show { print "x=$x\ty=$y\t\$#fibs=$#fibs\tfibs=@fibs\tscalar \@fibs = ", scalar @fibs, "\n"; }; $fibs[$#fibs+1] = 2; } show(); But I am unsure what you intend by the statement "$fibs[$#fibs+1] = 2;" and you need to be aware that this also will be executed at the start of run time. Alternatively, you could simply write code to do the initialisation on the first call of the subroutine: use strict; use warnings; show(); { my (@fibs, $x, $y, $init); sub show { if (not $init) { @fibs = (0,1,1); ($x, $y) = (1,2); $init++; } print "x=$x\ty=$y\t\$#fibs=$#fibs\tfibs=@fibs\tscalar \@fibs = ", scalar @fibs, "\n"; }; $fibs[$#fibs+1] = 2; } show(); I hope this helps. Rob -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/