Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Re: Re: Tribute to TMTOWTDI

by demerphq (Chancellor)
on Oct 26, 2001 at 16:59 UTC ( [id://121623]=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Tribute to TMTOWTDI
in thread Tribute to TMTOWTDI

Update
This node was written partially because I didn't grok the point that chipmunk was making, but I believe it still serves as a useful clarification of the quote below. The important point here is that chipmunk is talking about the Benchmark _file_ and not package. See the follow ups for some interesting implications of this subtle difference. Also I have removed the later portion of the quoted sentence 'where the lexical @a and @b are not in scope ' because it appears I am discussing the lexical variables, whereas I am not. My apologies.
End Update

The eval of the code snippets occurs within Benchmark,

Actually, this isn't correct. Benchmark goes through some interesting (not necessarily completely correct either)contortions to execute code from the package it was called from, in this case main.

This can be seen from this snippet from Benchmark::runloop which is the primary timing routine in Benchmark. (BTW, i only know this cause ive been working on a OO version of Benchmark, coming Real Soon Now to the Code Catacombs :-)

# find package of caller so we can execute code there my($curpack) = caller(0); my($i, $pack)= 0; while (($pack) = caller(++$i)) { last if $pack ne $curpack; } my ($subcode, $subref); if (ref $c eq 'CODE') { $subcode = "sub { for (1 .. $n) { local \$_; package $pack; &\$c; +} }"; $subref = eval $subcode; } else { $subcode = "sub { for (1 .. $n) { local \$_; package $pack; $c;} } +"; $subref = _doeval($subcode); }
Oh and a note to andreychek I dont think that including print,warn statements in a benchmark (unless warn() is what you are benchmarking) is a good idea. The overhead of them executing probably drowns out the difference between the functions. Yves / DeMerphq
--
Have you registered your Name Space?

Replies are listed 'Best First'.
Re: Re: Re: Re: Tribute to TMTOWTDI
by chipmunk (Parson) on Oct 26, 2001 at 17:51 UTC
    Regardless of any contortions Benchmark goes through to execute code in the calling package, lexical variables are not in any package. It is impossible for code to access lexical variables that are not in scope.

    This can be seen with a very simple Benchmark:

    #!perl use Benchmark; $main::variable = 'global'; my $variable = 'lexical'; timethese(1, { anon => sub { print "$variable\n"; }, string => 'print "$variable\n";', } ); __END__ Benchmark: timing 1 iterations of anon, string... lexical anon: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) (warning: too few iterations for a reliable count) global string: 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) (warning: too few iterations for a reliable count)
    The anonymous sub snippet accesses the lexical $variable, because the snippet is compiled in the same scope as the lexical variable. The string snippet accesses the global $variable, because the snippet is compiled in a completely separate scope, when the eval is executed.
      Regardless of any contortions Benchmark goes through to execute code in the calling package, lexical variables are not in any package. It is impossible for code to access lexical variables that are not in scope.

      No arguments here. My only problem with your post was the line I quoted. I've just reread your original post and you have to admit its a little ambiguous. Yes the code is executed inside of the _file_ Benchmark, but not in the package Benchmark. And this leads to an interesting point (about which Ill have to trawl the docs for at a later time) the two are different. Consider the below code

      #Put in file TestA.pm in a root lib directory package TestA; my $var="TestA"; 1; #Put in file TestB.pm in a root lib directory package TestB; use TestA; my $var2="TestB"; package TestA; print "'$var','$var2'"; 1;
      Now if you do perl TestB.pm you will see
      '','TestB'
      But if you stick the entire code snippet into TestB.pm then you will see
      'TestA','TestB'
      Even though you might expect that the lexical variable $var would be out of scope.

      (Incidentally I have a development Lib directory that I use for this type of stuff and have my enviornment configured to always include it.)
      Update
      It seems to me the moral of this is that when you put many packages in a single file everything following the package declaration should be placed into an anoymous block. Ie:

      package TestA; { my $var="TestA"; 1; } package TestB; { use TestA; my $var2="TestB"; } package TestA; { print "'$var','$var2'"; 1; }

      Yves / DeMerphq
      --
      Have you registered your Name Space?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://121623]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-04-19 04:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found