Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: "Andy" <anedza@xxxxxxxxxxxxxxxxxxxxxx>
- Date: 5 Feb 2007 11:32:43 -0800
Thanks Dominique!
I'ld like to recap/summarize this discussion thread to make it easier
for those reading it in the future.
Closure is the Perl equivalent of namespaces and encapsulation of
variables and code. Since Perl programs are executed by a central
interpreter, there is no O/S imposed isolation of scope between Perl
programs and the modules they call (they all run under the same
process the interpreter is on).
As long as you pass a reference (a memory address) for a variable or a
subroutine, that variable can be read/written or that subroutine can
be executed from anywhere, regardless of where it was first declared.
Reference passing through switches (such as -command) is a common way
for Perl/Tk programs and widgets to talk to each other.
To pass a reference for a subroutine declared in a Perl program to a
widget, prefix the subroutine's name with \&
To pass a reference for a variable declared in a Perl program to a
widget, prefix the variable's name with \$
To execute an externally referenced subroutine from inside a Perl
module, precede the variable that received the reference with &$ and
treat the entire thing as a normal subroutine call.
To work with the value in an externally referenced variable from
inside a Perl module, precede the variable that received the reference
with $$ and treat the entire thing as a normal variable.
ie, given myvar and mysub reside in your perl program
$myvar="hello world";
mysub{
($greeting) = @_;
print $$greeting;
}
you can have a perl module (or widget) directly access these items
without making any copies of anything by first passing the references:
-command => [\&mysub,\$myvar]
and having the receiving perl module (or widget) use the references to
execute the external code in some way:
modsub=shift; #captures the ref \&mysub
modvar=shift; #captures the ref \$myvar
&$modsub($$modvar); #call the external mysub method and pass it hello
world
The &$ and $$ are called dereferencing operators, and they can also be
used anywhere to "execute" a reference wherever it appears.
There are, however, some Perl Modules that execute a copy of
referenced code (by value) rather than doing it directly (by
reference).
These use another CPAN module called B::Deparse that is essentially a
Perl de-compiler. Given a reference, Deparse can expand the tokens it
finds there into Perl code using its coderef2text function:
use B::Deparse;
$deparse= B::Deparse->new();
modsub=shift; #captures the ref \&mysub
$modcode=$deparse->coderef2text(modsub); #modcode now contains mysub
listing
The Perl module then re-compiles the de-compiled code using eval() to
execute it:
eval($modcode);
This is useful when your Perl program needs memory to be persisted in-
between separate invocations of the Perl interpreter. Rather than
persisting addresses (which can change upon reloading), it's easier to
recreate whatever needs persistance and to assign it a new memory
address.
The tk::scheduler does this because it persists scheduled tasks, even
when it is shut down and restarted again at a later date. If the
scheduler stored the addresses to scheduled code, those addresses
could be invalid the next time it was reloaded back into the
interpreter. Instead, it stores a copy of the subroutine to be
executed, which is why I encountered all the previous access problems
to subroutines other than my main one - they weren't included in the
deparser decompile.
The deparser, however, is smart enough to include any package names
for the listing the decompiled code originally appeared in.
The package name acts as a namespace that identifies a particular
symbolic table that may exist in the Perl Interpreter. When the
eval() statement has a package name, it can access the symbolic table
to resolve any other references within the decompiled code that point
to code currently loaded in the Perl interpreter. In a way, execute
by value code can execute code by reference by using labels instead of
numeric memory addresses.
.
- Follow-Ups:
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: Dominique Dumont
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- References:
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: Dominique Dumont
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: Andy
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: Andy
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: Andy
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- From: Dominique Dumont
- Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- Prev by Date: Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- Next by Date: Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- Previous by thread: Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- Next by thread: Re: Perl Tk:Scheduler command called subroutine fails to talk to tk widgets
- Index(es):
Relevant Pages
|
|