http://qs1969.pair.com?node_id=771404


in reply to Dynamically Changing Packages w/out Eval

Umm, what is it you think that the package statement does in this code?

Because I'm hard pressed to think of anything that it might affect in the code you have posted. The vars are all lexical. So they arent modified at all by the package declaration.

And actually your language is imprecise. Packages arent containers really. Not in the sense you state. Package statements are instead merely hints to the compiler as to how to deal with non-fully qualified identifiers. Subs dont run "in a package" they are compile time bound to specific lexical and global variables, which may be affected by the presence of a package statement, and indeed unqualfied sub declarations are installed in the stash relative to the current package, but other than that, well, packages dont exist. Not as a first order concept or object.

So what *exactly* is the problem you are trying to solve? This has all the hallmarks of an XY question.

update: after discussing on #p5p it was suggested that maybe you want to do this so as to not confuse Carp::carp or Carp::croak. If so then, well, those routines are arguably broken. Dont use them, possibly by changing them to cluck/confess and the problem goes away.

---
$world=~s/war/peace/g

  • Comment on Re: Dynamically Changing Packages w/out Eval

Replies are listed 'Best First'.
Re^2: Dynamically Changing Packages w/out Eval
by Ovid (Cardinal) on Jun 15, 2009 at 06:34 UTC
    Umm, what is it you think that the package statement does in this code?

    Because I'm hard pressed to think of anything that it might affect in the code you have posted. The vars are all lexical. So they arent modified at all by the package declaration.

    I know that. I'm not that much of a Perl newbie :)

    The exact problem I'm trying to solve is the same thing Test::Aggregate does: run arbitrary bits of code and ensure that we don't have namespace pollution. If one chunk of code defines a package variable or creates a subroutine in its namespace, I don't want that clashing with other chunks of code. Hence, the package declaration.

      Sorry ovid, but the code you posted as an example did not make that very clear*. You basically cannot get rid of namespace pollution in perl. It is impossible. Any piece of code can declare objects in any namespace at any time.

      As far as /useful/ advice, :-), take a look at the top of Benchmark.pm and see how Jarkko did it.

      * Update: i mean it didnt make your question clear. I know you arent a newbie. Remember we drank a fair amount of whiskey together in vienna? ;-)

      ---
      $world=~s/war/peace/g

      Perhaps copying and restoring the symbol table does what you want?

      use Data::Dumper; package Foo; $foo="bar"; sub quux { print "\$foo is '$foo'\n" } package main; my %Foo_save = %Foo::; print "-1-\n",Dumper \%Foo::; eval "\$Foo::bar = q{quux}"; print "-2-\n",Dumper \%Foo::; print "-3-\n",Dumper \%Foo_save; %Foo:: = %Foo_save; print "-4-\n",Dumper \%Foo::; Foo::quux(); eval "print \"but Foo::bar is '\$Foo::bar'\\n\""; __END__ -1- $VAR1 = { 'quux' => *Foo::quux, 'foo' => *Foo::foo }; -2- $VAR1 = { 'bar' => *Foo::bar, 'quux' => *Foo::quux, 'foo' => *Foo::foo }; -3- $VAR1 = { 'quux' => *Foo::quux, 'foo' => *Foo::foo }; -4- $VAR1 = { 'quux' => *Foo::quux, 'foo' => *Foo::foo }; $foo is 'bar' but Foo::bar is ''

      That fails if eval'ed code populates a scalar slot of an already present typeglob - if, for instance, the subroutine in Foo was named 'bar', then $Foo::bar would retain the value set in the string eval. Hmm.. maybe Clone would help?