tclperl

a Perl package for Tcl




This package allows the execution of Perl code from a Tcl interpreter, as in:
  package require tclperl
  set interpreter [perl::interp new]
  $interpreter eval {print "Hello World\n"}
  perl::interp delete $interpreter

and, starting with version 3.0, execution of Tcl code from Perl interpreters, as in:
  package require tclperl 3
  set interpreter [perl::interp new]
  puts [$interpreter eval {
    $Tcl::parent->eval('clock format [clock seconds]');
  }]
  perl::interp delete $interpreter

It works by creating one (or possibly several) embedded Perl interpreter and sending it strings to evaluate. Binary modules can be loaded in the Perl interpreter as if it were the real Perl program.

As expected, eval returns whatever the Perl interpreter returns and reports an error at the Tcl level when the Perl interpreter itself fails in executing the code string. Of course, when evaluating Tcl code in the parent Tcl interpreter from the child Perl interpreter (second example above), any error in the Tcl code is passed to the Perl interpreter, which in turn forwards it to the hosting Tcl interpreter, except when threads are involved (see below).

You can actually create several Perl interpreters, if the tclperl package was linked against a Perl library compiled with -DMULTIPLICITY, otherwise only 1 Perl interpreter can exist at a time.

Be careful about STDIN, STDOUT and STDERR which are shared with the hosting Tcl interpreter.

Starting with tclperl 3.1, Perl threads are supported if the tclperl extension was built against a Perl library of version 5.6.0 or above, and the Tcl interpreter is also compiled with multithreading enabled. Note that eval returns nothing when Tcl code is executed from a Perl thread. Such Tcl code should be used to let the Tcl interpreter know that the work in the Perl thread is done, so that further actions can be taken.
Note that any errors in the Tcl script are reported to the standard error output.
The following example demonstrates a possible use of Perl threads:
  package require tclperl 3.1
  set interpreter [perl::interp new]
  $interpreter eval {
    use threads; use Thread::Queue;
    our $queue = Thread::Queue->new();
    sub work() {
      while (1) {
        sleep(2);
        $queue->enqueue(rand(100));
        $Tcl::parent->eval('set done 1');
      }
    }
    threads->new(\&work);
  }
  puts running...
  vwait done
  $interpreter eval {
    my $data = $queue->dequeue();
    print("got $data\n");
  }

If you wish to extend the tclperl extension, for example to bring more functionality to the Perl side, you can obviously write pure Perl modules, but also access the hosting Tcl interpreter from C code by using the following function declaration:
  extern Tcl_Interp *tclInterpreter(char *);

where the parent Tcl interpreter is returned from a name. At this time, there can be only 1 hosting Tcl interpreter, whose name is always "tcl0".

Note: tclperl is used by the moodss system monitoring software (information on my homepage) to allow its modules to be written in Perl as well as Tcl. Look at the Random and Threaded modules for more sample code.

Send your comments, bug reports, ... to jfontain@free.fr.
My homepage is at http://jfontain.free.fr/.