Aliasing Lexicals 
Author Message
 Aliasing Lexicals

Is there anything 'Bad (tm)' about creating a selective typeglob alias
in
one package to a lexical that is definitely going to go out of scope in
a
second package? It seems to work, but I feel like I may be missing
something...

For example, consider two packages, A and B. B has a subroutine which
executes the following (B knows about A):

sub foobar {
  my $lexval = 'foo';
  *A::bar = \$lexval;

Quote:
}

My concern is that B::foobar is going to get called possibly multiple
times
(it is okay that $A::bar is getting overwritten each time B::foobar gets

called, and no other slots in *A::bar are used.) Since $A::bar ends up
holding the only reference to $lexval once B::foobar exits, is the
refcount
decremented and the first instance of $lexval cleaned up properly when
B::foobar gets called a second time, overwriting $A::bar?

--Chris



Mon, 23 Sep 2002 03:00:00 GMT  
 Aliasing Lexicals

Quote:

> For example, consider two packages, A and B. B has a subroutine which
> executes the following (B knows about A):

> sub foobar {
>   my $lexval = 'foo';
>   *A::bar = \$lexval;
> }

> My concern is that B::foobar is going to get called possibly multiple
> times
> (it is okay that $A::bar is getting overwritten each time B::foobar gets

> called, and no other slots in *A::bar are used.) Since $A::bar ends up
> holding the only reference to $lexval once B::foobar exits, is the
> refcount
> decremented and the first instance of $lexval cleaned up properly when
> B::foobar gets called a second time, overwriting $A::bar?

Yes.

What's that?  You'd like a slightly longer answer?  :-)

Okay.  If we bless an object into package Pkg then Pkg::DESTROY is
called when the object is destroyed.  So let's modify your function
foobar so that $lexvar is a reference to a blessed object.  If the
refcount is correctly decremented when $A::bar is overwritten, DESTROY
will be called, and we can stick a print statement in there as
evidence.

        #!perl -w

        package Pkg;

        sub new
        {       bless \(my $a = $_[1]);
        }

        sub DESTROY
        {       print "DESTROYing $_[0]\n";
        }

        package B;

        sub foobar($)
        {       my $lexvar = new Pkg shift;
                *A::bar = \$lexvar;
        }

        for (qw/one two three/)
        {       foobar $_;
                print $$A::bar, "\n";
                print "\$A::bar = $A::bar\n";
        }

Package Pkg has a simple constructor that returns a reference to a
blessed scalar.  The blessed scalar holds whatever was passed as the
first argument to the constructor.  So if you say

        new Pkg 'Zaphod'

you get a reference to a blessed scalar containing the string
'Zaphod'.  When the last reference is destroyed, the scalar is
destroyed and sub DESTROY is called.

If you run this code, it produces something like this:

        one
        $A::bar = Pkg=SCALAR(0x8b9223c)
        DESTROYing Pkg=SCALAR(0x8b9223c)
        two
        $A::bar = Pkg=SCALAR(0x8b9f19c)
        DESTROYing Pkg=SCALAR(0x8b9f19c)
        three
        $A::bar = Pkg=SCALAR(0x8b9f1b4)
        DESTROYing Pkg=SCALAR(0x8b9f1b4)

On each iteration through the loop, the old reference is destroyed
when $A::bar is overwritten.  On each occasion, $A::bar holds the last
reference to the Pkg object; when $A::bar is overwritten, the object
is destroyed and DESTROY is called.

Markus

--
Web site of the week: <http://www.mailexpire.com/>



Tue, 24 Sep 2002 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Aliasing Lexicals

2. s// using lexicals and refs in an eval'ed string

3. Closure and Lexicals: Am I confused?

4. BEGIN and lexicals

5. docs for typed lexicals

6. 1.lexicals 2.use vs require

7. Visibility of package lexicals in debugger

8. Destruction of lexicals (surprise)

9. aliasing package names in Perl 5.6.0

10. Aliasing module names?

11. Lexical aliasing

12. Aliasing special variables?

 

 
Powered by phpBB® Forum Software