> my $sub = sub {
> my ($X, $Y) = (Tcl::Ev('X'), Tcl::Ev('Y'));
> print "X: $X Y: $Y\n";
> };
> $mw->bind('<Motion>', \\'XY', $sub);
OK, I've manage to make this work, so the above would be
written as:
my $sub = sub {
print STDERR "CALLBACK (@_)\n";
};
$mw->bind('<Motion>', [$sub, Tcl::EV('%X', '%Y'), '<Motion>']);
and that would end up printing out something like:
CALLBACK (440 532 <Motion>)
I think this is a much cleaner way to operate. It allows you
to declare the %-subs you want, like you do in Tcl, and it
passes them to your sub. The only limitation is that the
Tcl::EV(...) must come first in the args set, although that is
just a convenience for now. The core pieces of the code to
make this work in Tcl.pm are:
in Tcl.pm:call():
elsif ($ref eq 'ARRAY' && ref($arg->[0]) eq 'CODE') {
# We have been passed something like [\&subroutine, $arg1, ...]
# Create a proc in Tcl that invokes this subroutine with args
my $events;
if ($#$arg >= 1 && ref($arg->[1]) eq 'Tcl::EV') {
$events = splice(@$arg, 1, 1);
}
$args[$argcnt] =
$interp->create_tcl_sub(sub {
splice @_, 0, 3; # remove ClientData, Interp and CmdName
$arg->[0]->(@_, @$arg[1..$#$arg]);
}, $events);
}
in Tcl.pm:
sub create_tcl_sub {
my ($interp,$sub,$events,$tclname) = @_;
unless ($tclname) {
# stringify sub, becomes "CODE(0x######)" in ::perl namespace
$tclname = "::perl::$sub";
}
unless (exists $anon_refs{$tclname}) {
$anon_refs{$tclname}++;
$interp->CreateCommand($tclname, $sub);
}
if ($events) {
$tclname = "$tclname " . join(' ', @{$events});
}
return $tclname;
}
sub EV {
my @events = @_;
return bless \@events, "Tcl::EV";
}
and then we can get rid of all the other Ev ref stuff. While this
might not be "ideal", I find it much more logical and easier to work
with than the previous solution. You could auto-prepend each %, but
I think it's good to keep the logical connection of %-sub there.
Note that this also changes/corrects the call to code refs that take
args to called subroutines to pass args from Tcl first, before the
args that were given in perl.
In somewhat related changes, code and variables created in Tcl from
Perl go into the ::perl namespace in Tcl.
Jeff
|