>> Users can (and do) write open code in modules.

> I don't understand.  Do you think that needs to be prevented?

No, I just want to know what happens when they do it.
Let's look at an example.

1. Non-threaded

    #!/usr/local/bin/perl

    sub foo { print 1 }
    foo();
    eval 'sub foo { print 2 }';
    foo();

When the compiler sees

    sub foo { print 1 }

it

1. builds an op tree for the block `{ print 1 }'
2. creates a code ref that points to the op tree
3. creates a glob that points to the code ref
4. sets $main::{foo} to the glob


Graphically:

    %main::
    key   value
    foo   *main::foo

    *main::foo
    SCALAR -> undef
    ARRAY  -> undef
    HASH   -> undef
    CODE   -> &main::foo

    &main::foo
    OPTREE -> { print 1 }


When the interpreter sees

    eval 'sub foo { print 2 }';

it calls the compiler, which

1. builds a new op tree for the block `{ print 2 }'
2. creates a new code ref that points to the new op tree
3. sets the CODE pointer in the *main::foo glob to the new code ref
4. decrements the reference count on the old code ref.
   If the ref count goes to zero, 
   it deletes the old code ref and its op tree

Both calls to

    foo();

are bound to the *main::foo glob at compile time. When the interpreter
executes a call, it follows the CODE pointer from the glob to the code
ref, follows the OPTREE pointer from the code ref to the op tree,
and finally walks the op tree.

This program outputs

    12


2. Threaded
I will write `global::' vice `main::' for the global stash, 
and write `thread::' for the thread local stash.

    #!/usr/local/bin/perl
    use Threads;

    sub foo { print 1 }
    foo();
    Threads->new(\&hack_foo)->join;
    foo();

    sub hack_foo { eval 'sub foo { print 2 }' }


At (initial) compile time, the compiler sets

    STASH             GLOB            CODE REF        OP TREE
    $global::{foo} -> *global::foo -> &global::foo -> { print 1 }

The question is where { print 2 } goes. Do we get

    $global::{foo} -> *global::foo -> &global::foo -> { print 2 }

as in the non-threaded case, or do we get

    $global::{foo} -> *global::foo -> &global::foo -> { print 1 }
    $thread::{foo} -> *thread::foo -> &thread::foo -> { print 2 }
        
Does this program output

    12

or 

    11


- SWM

Reply via email to