cache and the interpreter

cache and the interpreter

am 06.05.2011 02:21:53 von Mike McClain

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.

Any hints will be appreciated.
Thanks,
Mike McClain
--
Satisfied user of Linux since 1997.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: cache and the interpreter

am 06.05.2011 02:33:10 von Uri Guttman

>>>>> "MM" == Mike McClain writes:

MM> Here's a simple example that illustrates the problem I've run into:
MM> perl -le'
MM> show();
MM> { my @fibs = (0,1,1); my ($x, $y) = (1,2);
MM> sub show
MM> { print "x=$x\ty=$y\t\$#fibs=$#fibs\tfibs=@fibs\tscalar \@fibs = ",
MM> scalar @fibs;
MM> };
MM> $fibs[$#fibs+1] = 2;
MM> }
MM> show();
MM> '
MM> x= y= $#fibs=-1 fibs= scalar @fibs = 0
MM> x=1 y=2 $#fibs=3 fibs=0 1 1 2 scalar @fibs = 4

MM> The first time show() runs it acts as if it can't see $x, $y or @fibs.
MM> The second time it does yet the interpreter had to have seen $x, $y
MM> and @fibs in order to find the definition of show().

MM> I've grown accustomed to writing 'C' style code in Perl with
MM> main before the subs rather than shell or Forth style but here it
MM> seems to fail.

this is perl, not c. don't write c style or expect c style to make sense.

MM> I know I can use memoize but where I ran across this problem
MM> was in trying to write a fibonacci routine that would take
MM> advantage of any previously calculated values rather than starting
MM> at 1 again as a memoized function would be required to do.

this is a simple problem and it is in your understanding of how perl
works, in particular how code is compiled vs run.

perl first compiles code to an intermediate form. then it executes
it. my commands have two phases, the declare phase which is handled
during the compiling and the assignment phase which is handled at run
time. the first time you call show(), the vars are declared but NOT
initialized. the second time you call show they are initialized.

you can solve this in several ways. one, use a BEGIN block instead of
the plain block you have. why do you have a block there at all? do you
need private scoping? the BEGIN block executes its code at compile time
so the initialization will happen before the first call to show.

you can also put the initializing code (not the declarations) in its own
sub and call that first before show is called. that way you control the
time things happen.

finally, why do you want to call show before the block anyhow? it won't
work as is and it can be subtly broken in other ways.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: cache and the interpreter

am 06.05.2011 09:16:14 von Rob Dixon

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-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: cache and the interpreter

am 06.05.2011 20:16:33 von rvtol+usenet

On 2011-05-06 02:21, Mike McClain wrote:

> $fibs[$#fibs+1] = 2;

push @fibs, 2;

--
Ruud


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: cache and the interpreter

am 07.05.2011 03:18:27 von Mike McClain

On Fri, May 06, 2011 at 08:16:14AM +0100, Rob Dixon wrote:
> On 06/05/2011 01:21, Mike McClain wrote:
> >
> > Here's a simple example that illustrates the problem I've run into:

> 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.

Thanks, I've the second edition which is not quite so explicit
and INIT is not in the index nor where BEGIN and END are discussed
but the above clearly explains why I wasn't getting what I expected.

> 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:


> INIT {

This is the solution I needed.

> 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.

The code in my post was just to explore very simply what I was seeing
in a much larger program and the statement you mention had no purpose
other than to help me see where the problem lay.
Sorry if it was confusing.

> Alternatively, you could simply write code to do the initialisation on
> the first call of the subroutine:


Since the problem that brought this up is a procedure for generating
Fibbonacci numbers that may be called thousands of times an extra test
would be less than optimal but I'll keep it in mind since I may have a
use for it another day.

> I hope this helps.
>
> Rob

Absolutely a big help.
Not only did you supply an explanation but a solution.
Best answer possible.

Thanks again,
Mike

--
Satisfied user of Linux since 1997.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: cache and the interpreter

am 07.05.2011 05:25:54 von Uri Guttman

>>>>> "MM" == Mike McClain writes:

>> INIT {

MM> This is the solution I needed.

MM> Absolutely a big help.
MM> Not only did you supply an explanation but a solution.
MM> Best answer possible.

not to rain on your parade but from your point of view INIT and BEGIN
are the same thing. they may execute at different times but both execute
before the main line code runs. you don't see INIT nearly as much as
BEGIN since not much code needs that small difference in execution
timing. i would stick with BEGIN since it is more common and more will
know what it means.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/