|
|
| |
Tcl(3) |
User Contributed Perl Documentation |
Tcl(3) |
Tcl - Tcl extension module for Perl
use Tcl;
$interp = Tcl->new;
$interp->Eval('puts "Hello world"');
The Tcl extension module gives access to the Tcl library with functionality and
interface similar to the C functions of Tcl. In other words, you can
- create Tcl interpreters
The Tcl interpreters so created are Perl objects whose
destructors delete the interpreters cleanly when appropriate.
- execute Tcl code in an interpreter
The code can come from strings, files or Perl filehandles.
- bind in new Tcl procedures
The new procedures can be either C code (with addresses
presumably obtained using dl_open and dl_find_symbol) or
Perl subroutines (by name, reference or as anonymous subs). The
(optional) deleteProc callback in the latter case is another perl
subroutine which is called when the command is explicitly deleted by
name or else when the destructor for the interpreter object is
explicitly or implicitly called.
- Manipulate the result field of a Tcl interpreter
- Set and get values of variables in a Tcl interpreter
- Tie perl variables to variables in a Tcl interpreter
The variables can be either scalars or hashes.
To create a new Tcl interpreter, use
$interp = Tcl->new;
The following methods and routines can then be used on the Perl
object returned (the object argument omitted in each case).
- $interp->Init ()
- Invoke Tcl_Init on the interpreter.
- $interp->CreateSlave (NAME, SAFE)
- Invoke Tcl_CreateSlave on the interpreter. Name is arbitrary. The
safe variable, if true, creates a safe sandbox interpreter.
See: http://www.tcl.tk/software/plugin/safetcl.html
http://www.tcl.tk/man/tcl8.4/TclCmd/safe.htm
This command returns a new interpreter.
- $interp->Eval (STRING, FLAGS)
- Evaluate script STRING in the interpreter. If the script returns
successfully (TCL_OK) then the Perl return value corresponds to Tcl
interpreter's result otherwise a die exception is raised with the
$@ variable corresponding to Tcl's interpreter result object. In each
case, corresponds means that if the method is called in scalar
context then the string result is returned but if the method is called in
list context then the result is split as a Tcl list and returned as a Perl
list. The FLAGS field is optional and can be a bitwise OR of the constants
Tcl::EVAL_GLOBAL or Tcl::EVAL_DIRECT.
- $interp->GlobalEval (STRING)
- REMOVED. Evalulate script STRING at global level. Call Eval(STRING,
Tcl::EVAL_GLOBAL) instead.
- $interp->EvalFile (FILENAME)
- Evaluate the contents of the file with name FILENAME. Otherwise, the same
as Eval() above.
- $interp->EvalFileHandle (FILEHANDLE)
- Evaluate the contents of the Perl filehandle FILEHANDLE. Otherwise, the
same as Eval() above. Useful when using the filehandle DATA to tack
on a Tcl script following an __END__ token.
- $interp->call (PROC, ARG, ...)
- Looks up procedure PROC in the interpreter and invokes it using Tcl's eval
semantics that does command tracing and will use the ::unknown (AUTOLOAD)
mechanism. The arguments (ARG, ...) are not passed through the Tcl parser.
For example, spaces embedded in any ARG will not cause it to be split into
two Tcl arguments before being passed to PROC.
Before invoking procedure PROC special processing is performed
on ARG list:
1. All subroutine references within ARG will be substituted
with Tcl name which is responsible to invoke this subroutine. This Tcl
name will be created using CreateCommand subroutine (see below).
2. All references to scalars will be substituted with names of
Tcl variables transformed appropriately.
These first two items allow one to write and expect it to work
properly such code as:
my $r = 'aaaa';
button(".d", -textvariable => \$r, -command=>sub {$r++});
3. All references to hashes will be substituted with names of
Tcl array variables transformed appropriately.
4. As a special case, there is a mechanism to deal with Tk's
special event variables (they are mentioned as '%x', '%y' and so on
throughout Tcl). When creating a subroutine reference that uses such
variables, you must declare the desired variables using Tcl::Ev as the
first argument to the subroutine. Example:
sub textPaste {
my ($x,$y,$w) = @_;
widget($w)->insert("\@$x,$y", $interp->Eval('selection get'));
}
$widget->bind('<2>', [\&textPaste, Tcl::Ev('%x', '%y'), $widget] );
- $interp->return_ref (NAME)
- returns a reference corresponding to NAME, which was associated during
previously called
"$interpnt->call(...)" preprocessing.
As a typical example this could be variable associated with a widget.
- $interp->delete_ref (NAME)
- deletes and returns a reference corresponding to NAME, which was
associated during previously called
"$interpnt->call(...)" preprocessing.
this follows _code_dispose about if NAME is a TClNAME or a DESCNAME. if
NAME is a VARNAME then it is just deleted and returned.
- $interp->icall (PROC, ARG, ...)
- Looks up procedure PROC in the interpreter and invokes it using Tcl's eval
semantics that does command tracing and will use the ::unknown (AUTOLOAD)
mechanism. The arguments (ARG, ...) are not passed through the Tcl parser.
For example, spaces embedded in any ARG will not cause it to be split into
two Tcl arguments before being passed to PROC.
This is the lower-level procedure that the 'call' method uses.
Arguments are converted efficiently from Perl SVs to Tcl_Objs. A Perl AV
array becomes a Tcl_ListObj, an SvIV becomes a Tcl_IntObj, etc. The
reverse conversion is done to the result.
- $interp->invoke (PROC, ARG, ...)
- Looks up procedure PROC in the interpreter and invokes it directly with
arguments (ARG, ...) without passing through the Tcl parser. For example,
spaces embedded in any ARG will not cause it to be split into two Tcl
arguments before being passed to PROC. This differs from icall/call in
that it directly invokes the command name without allowing for command
tracing or making use of Tcl's unknown (AUTOLOAD) mechanism. If the
command does not already exist in the interpreter, and error will be
thrown.
Arguments are converted efficiently from Perl SVs to Tcl_Objs.
A Perl AV array becomes a Tcl_ListObj, an SvIV becomes a Tcl_IntObj,
etc. The reverse conversion is done to the result.
- Tcl::Ev (FIELD, ...)
- Used to declare %-substitution variables of interest to a subroutine
callback. FIELD is expected to be of the form "%#" where # is a
single character, and multiple fields may be specified. Returns a blessed
object that the 'call' method will recognize when it is passed as the
first argument to a subroutine in a callback. See description of 'call'
method for details.
- $interp->result ()
- Returns the current Tcl interpreter result. List v. scalar context is
handled as in Eval() above.
- $interp->CreateCommand (CMDNAME, CMDPROC, CLIENTDATA, DELETEPROC,
FLAGS)
- Binds a new procedure named CMDNAME into the interpreter. The CLIENTDATA
and DELETEPROC arguments are optional. There are two cases:
(1) CMDPROC is the address of a C function
(presumably obtained using dl_open and
dl_find_symbol. In this case CLIENTDATA and DELETEPROC are taken
to be raw data of the ClientData and deleteProc field presumably
obtained in a similar way.
(2) CMDPROC is a Perl subroutine
(either a sub name, a sub reference or an anonymous sub). In
this case CLIENTDATA can be any perl scalar (e.g. a ref to some other
data) and DELETEPROC must be a perl sub too. When CMDNAME is invoked in
the Tcl interpreter, the arguments passed to the Perl sub CMDPROC
are
(CLIENTDATA, INTERP, LIST)
where INTERP is a Perl object for the Tcl interpreter which
called out and LIST is a Perl list of the arguments CMDNAME was called
with. If the 1-bit of FLAGS is set then the 3 first arguments on the
call to CMDPROC are suppressed. As usual in Tcl, the first element of
the list is CMDNAME itself. When CMDNAME is deleted from the interpreter
(either explicitly with DeleteCommand or because the destructor
for the interpreter object is called), it is passed the single argument
CLIENTDATA.
- $interp->DeleteCommand (CMDNAME)
- Deletes command CMDNAME from the interpreter. If the command was created
with a DELETEPROC (see CreateCommand above), then it is invoked at
this point. When a Tcl interpreter object is destroyed either explicitly
or implicitly, an implicit DeleteCommand happens on all its
currently registered commands.
- (TCLNAME,GENCODE) = $interp->create_tcl_sub(CODEREF, EVENTS, TCLNAME,
DESCRNAME)
- Creates a COMMAND called TCLNAME calling CODEREF in the interpreter
$interp, and adds it to the internal tracking
structure. DESCRNAME and TCLNAME should not begin with = or @ or ::perl::
to avoid colisions If TCLNAME IS blank or undef, it is constructed from
the CODEREF address. GENCODE starts as TCLNAME but gets @$EVENTS which can
contain %vars joined to it.
TCLNAME and DESCRNAME get stored in an internal structure, and
can be used to purge things fRom the command table via code_destroy or
$interp->delete_ref;
Returns (TCLNAME,GENCODE). if you are creating code refs with
this you can continue to use the same coderef and it will be converted
on each call. but if you save GENCODE, you can replace the anon-coderef
call in the tcl command with GENCODE.
for instance
$interp->call('FILEEVENT',$fileref,WRITABLE=>sub {...});
can be replaced by
my ($tclcode,$gencode)=$interp->create_tcl_sub(sub{...}, EVENTS, TCLNAME, DESCRNAME);
$interp->call('FILEEVENT',$gencode,WRITABLE=>$gencode);
or
my $sub=sub{....};
$interp->call('FILEEVENT',$fileref,WRITABLE=>$sub);
can be replaced by
my ($tclcode,$gencode)=$interp->create_tcl_sub($sub, EVENTS, TCLNAME, DESCRNAME);
$interp->call('FILEEVENT',$gencode,WRITABLE=>$gencode);
although
$interp->call('FILEEVENT',$fileref,WRITABLE=>$sub);
will stil work fine too.
Then you later call
$interp->delete_ref($tclname);
when you are finished with that sub to clean it from the
internal tracking and command table. This means no automatic cleanup
will occur on the sub{...} or $sub
And after the destroy inside Tcl any triggering writable on
$fileref will fail as well. so it should be
replaced first via
$interp->call('FILEEVENT',$fileref,WRITABLE=>'');
- (CODEREF) = Tcl::_code_dispose(NAME)
- Purges the internal table of a NAME and may initiate destruction of
something created thru call or create_tcl_sub
TCLNAME and DESCRNAME get stored in an internal structure, and
can be used to purge things form the command table. calling
_code_dispose on a TCLNAME retruned from create_tcl_sub removes all use
instances and purges the command table. calling _code_dispose on a
DESCRNAME passed to create_tcl_sub removes only that instace Code used
in a DESCRNAME may be used in other places as well, only when the last
usage is purged does the entry get purged from the command table
While the internal tracking structure saves the INTERP the
code was added to, it itself does not keep things separated by INTERP, A
TCLNAME or DESCRNAMe can only exist in one INTERP at a time, using a new
INTERP just causes the one in the last INTERP to disappear, and probably
end up with the Tcl code getting deleted
Returns (CODEREF), this is the original coderef
- $interp->SetResult (STRING)
- Sets Tcl interpreter result to STRING.
- $interp->AppendResult (LIST)
- Appends each element of LIST to Tcl's interpreter result object.
- $interp->AppendElement (STRING)
- Appends STRING to Tcl interpreter result object as an extra Tcl list
element.
- $interp->ResetResult ()
- Resets Tcl interpreter result.
- $interp->SplitList (STRING)
- Splits STRING as a Tcl list. Returns a Perl list or the empty list if
there was an error (i.e. STRING was not a properly formed Tcl list). In
the latter case, the error message is left in Tcl's interpreter result
object.
- $interp->SetVar (VARNAME, VALUE, FLAGS)
- The FLAGS field is optional. Sets Tcl variable VARNAME in the interpreter
to VALUE. The FLAGS argument is the usual Tcl one and can be a bitwise OR
of the constants Tcl::GLOBAL_ONLY, Tcl::LEAVE_ERR_MSG, Tcl::APPEND_VALUE,
Tcl::LIST_ELEMENT.
- $interp->SetVar2 (VARNAME1, VARNAME2, VALUE, FLAGS)
- Sets the element VARNAME1(VARNAME2) of a Tcl array to VALUE. The optional
argument FLAGS behaves as in SetVar above.
- $interp->GetVar (VARNAME, FLAGS)
- Returns the value of Tcl variable VARNAME. The optional argument FLAGS
behaves as in SetVar above.
- $interp->GetVar2 (VARNAME1, VARNAME2, FLAGS)
- Returns the value of the element VARNAME1(VARNAME2) of a Tcl array. The
optional argument FLAGS behaves as in SetVar above.
- $interp->UnsetVar (VARNAME, FLAGS)
- Unsets Tcl variable VARNAME. The optional argument FLAGS behaves as in
SetVar above.
- $interp->UnsetVar2 (VARNAME1, VARNAME2, FLAGS)
- Unsets the element VARNAME1(VARNAME2) of a Tcl array. The optional
argument FLAGS behaves as in SetVar above.
In V1.03 command table cleanup was intoduced. This tries to keep the internal
structure and command table clean. In V1.02 and prior heavy use of sub { .. }
in Tcl commands could pollute these tables as they were never cleared. Command
table cleanup tries to alieviate this.
if you call create_tcl_sub the internal reference exists until you
delete_ref or _code_dispose it, or you call create_tcl_sub with the same
DESCRNAME.
if the internal reference was created internaly by call(...) there
are two rules
- 1)
- If the command is an "after" the internal references is keept at
least until 1 second after the delay. If there are still other
"users" of the TCLNAME then it is not deleted until the last one
goes away. If another call with the same CODEREF happens before this, then
it will get registered as a "user" without any need to
delete/recreate the tcl command first.
- 2)
- otherwise a DESCRNAME is created with the text sections of the command,
prefaced by "=". Like "=after 1000" or "=:.m.m
add command -command -label Exit" or "=::button .f3.b8 -text
conn -command" or "=gets sock9ac2b50" or "=fileevent
sock9827430 writable"
the TCLCODES created for that command will be kept at least
until a command with the same DESCRNAME and containing a subroutine
reference is run again. Since many DESCRNAMES can reference the same
TCLNAME only when the last DESCRNAME referencing a TCLNAME is released
is the TCLNAME purged.
NOTE: Since
$interp->call('fileevent','sock9827430','writable');
does not contain a subroutine reference, it will not release/free the
TCLNAME/DESCRNAME created by
$interp->call('fileevent','sock9827430','writable',sub{...});
even though that is the way you deactivate a writable/readable callback
in Tcl.
Prior to V1.06 there was also a problem with the coderef never
getting cleared from sas, a refcount was kept at the PVCV that prevented it
from getting garbage collected, but that SV itself got "lost" and
could never be garbage collected, thereby also keeping anything in that
codes PAD.
To assist in tracking chages to the internal table and the
commands table 3 trace subs were added, set them to non-blank or non-zero to
add the tracking output to SYSOUT, like this in your code:
sub Tcl::TRACE_SHOWCODE(){1}
- Tcl::TRACE_SHOWCODE
- Display all generated Tcl code by call(). Be aware: Tkx::MainLoop
runs by issuing a lot of "winfo exists ." calls, a LOT. But this
is a nice way to tell what your programs are doing to Tcl.
- Tcl::TRACE_CREATECOMMAND
- Display Tcl subroutine creation by call/create_tcl_sub
- Tcl::TRACE_DELETECOMMAND
- Display Tcl subroutine deletion by cleanup/delete_ref/_code_dispose
You can tie a Perl variable (scalar or hash) into class Tcl::Var so that
changes to a Tcl variable automatically "change" the value of the
Perl variable. In fact, as usual with Perl tied variables, its current value
is just fetched from the Tcl variable when needed and setting the Perl
variable triggers the setting of the Tcl variable.
To tie a Perl scalar $scalar to the Tcl
variable tclscalar in interpreter $interp with
optional flags $flags (see SetVar above),
use
tie $scalar, "Tcl::Var", $interp, "tclscalar", $flags;
Omit the $flags argument if not wanted.
To tie a Perl hash %hash to the Tcl array
variable array in interpreter $interp with
optional flags $flags (see SetVar above),
use
tie %hash, "Tcl::Var", $interp, "array", $flags;
Omit the $flags argument if not wanted. Any
alteration to Perl variable $hash{"key"}
affects the Tcl variable array(key) and vice versa.
After creation of Tcl interpreter, in addition to evaluation of Tcl/Tk commands
within Perl, other way round also instantiated. Within a special namespace
" ::perl " following objects are created:
::perl::Eval
So it is possible to use Perl objects from within Tcl.
NOTE: explanations below is for developers managing Tcl/Tk installations itself,
users should skip this section.
In order to create Tcl/Tk application with this module, you need
to make sure that Tcl/Tk is available within visibility of this module.
There are many ways to achieve this, varying on ease of starting things up
and providing flexible moveable archived files.
Following list enumerates them, in order of increased possibility
to change location.
- First method
Install Tcl/Tk first, then install Perl module Tcl, so
installed Tcl/Tk will be used. This is most normal approach, and no care
of Tcl/Tk distribution is taken on Perl side (this is done on Tcl/Tk
side)
- Second method
Copy installed Tcl/Tk binaries to some location, then install
Perl module Tcl with a special action to make Tcl.pm know of this
location. This approach makes sure that only chosen Tcl installation is
used.
- Third method
During compiling Tcl Perl module, Tcl/Tk could be statically
linked into module's shared library and all other files zipped into a
single archive, so each file extracted when needed.
To link Tcl/Tk binaries, prepare their libraries and then
instruct Makefile.PL to use these libraries in a link stage. (TODO
provide better detailed description)
- export_to_tcl method
- An interpreter method, export_to_tcl, is used to expose a number of perl
subroutines and variables all at once into tcl/tk.
export_to_tcl takes a hash as arguments, which
represents named parameters, with following allowed values:
- namespace => '...'
- tcl namespace, where commands and variables are to be created, defaults to
'perl'. If '' is specified - then global namespace is used. A possible
'::' at end is stripped.
- subs => { ... }
- anonymous hash of subs to be created in Tcl, in the form /tcl name/ =>
/code ref/
- vars => { ... }
- anonymous hash of vars to be created in Tcl, in the form /tcl name/ =>
/code ref/
- subs_from => '...'
- a name of Perl namespace, from where all existing subroutines will be
searched and Tcl command will be created for each of them.
- vars_from => '...'
- a name of Perl namespace, from where all existing variables will be
searched, and each such variable will be tied to Tcl.
An example:
use strict;
use Tcl;
my $int = Tcl->new;
$tcl::foo = 'qwerty';
$int->export_to_tcl(subs_from=>'tcl',vars_from=>'tcl');
$int->Eval(<<'EOS');
package require Tk
button .b1 -text {a fluffy button} -command perl::fluffy_sub
button .b2 -text {a foo button} -command perl::foo
entry .e -textvariable perl::foo
pack .b1 .b2 .e
focus .b2
tkwait window .
EOS
sub tcl::fluffy_sub {
print "Hi, I am a fluffy sub\n";
}
sub tcl::foo {
print "Hi, I am foo\n";
$tcl::foo++;
}
- export_tcl_namespace
- extra convenience sub, binds to tcl all subs and vars from perl
tcl:: namespace
Malcolm Beattie, 23 Oct 1994
Vadim Konovalov, 19 May 2003
Jeff Hobbs, jeff (a) activestate . com, 22 Mar 2004
Gisle Aas, gisle (a) activestate . com, 14 Apr 2004
Special thanks for contributions to Jan Dubois, Slaven Rezic, Paul
Cochrane, Huck Finn, Christopher Chavez, SJ Luo.
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
See http://www.perl.com/perl/misc/Artistic.html
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |