I don't like to use the name 'bind_...' for this.  To me it sounds like this 
would bind the namespace together so that subs created after the call also 
become visible to Tcl and perhaps even that commands created on the Tcl side 
become visible to Perl.

My suggestion would be to make a convenience method like this one:

$interp->create_commands(
    namespace => "perl",
    subs => {
        foo => sub { .... },
        bar => sub { .... },
    }
);

where the "namespace" argument is optional.  It's the Tcl namespace where the 
commands will be created. If not provided the names will be registered in the 
root namespace.  This would also always call the underlying 
$interp->CreateCommand with FLAGS=1 in order to suppress the confusing initial 
legacy arguments.  The keys of the subs hash could also use "::ns::foo" style 
names in which case the namespace argument is ignored for that particular key.

Your use case would then be covered by:

$interp->create_commands(
    namespace => "perl",
    subs => \%{"tcl\::"},
);

which is a bit ugly to write so you might be able to provide some sugar like:

$interp->create_commands(
    namespace => "perl",
    subs_from => "tcl",
);

if 'subs' and 'subs_from' are provided together they both contribute; with 
'subs' taking preference in case there are conflicting names.  Alternatively 
croak on conflicting names.

I would also suggest a 'only => \@list_of_names' argument to be able to limit 
the names to export to Tcl.

Regards,
Gisle



On Jan 18, 2011, at 17:20 , Konovalov, Vadim (Vadim)** CTR ** wrote:

>> From: Jeff Hobbs [mailto:je...@activestate.com] 
>> On 15/01/2011 1:35 PM, Konovalov, Vadim (Vadim)** CTR ** wrote:
>>> I wonder, is it reasonable for this approach to be 
>> "standartized" and included to, say, Tcl.pm module?
>>> 
>>> For example - all Tcl names from some predefined Tcl 
>> namespace could be bound to perl subroutines all at once.
>> 
>> I think it would be good to provide this as a standard convenience 
>> function, that would tie either a Perl or Tcl namespace to the other 
>> language.  I don't think we'd want to pre-define the namespace (note 
>> that Tcl.pm already uses ::perl:: on the Tcl side), but let the user 
>> pick it with a single command invocation.
> 
> Indeed, Tcl.pm uses ::perl:: in Tcl::call.
> 
> All refs in this namespace have names like "SCALAR(0xXXXXXX)" or 
> "CODE(0x######)", and it is very unlikely to have a collision. IOW, the 
> collision could happen if a user have an intention to create a collision, but 
> he/she could just create such a collision anyway, by creating conflicting 
> names using another existing mechanisms.
> 
> Ok, below is my suggestion to include to Tcl.pm,
> 
> 
> =comment
> An interpreter method, bind_perl_to_tcl_commands, takes two optional
> arguments - tcl package name (defaults to 'tcl' and perl package name
> (defaults to 'tcl')
> 
> Given a number of Perl sub's in said package, which is passed as the
> second parameter, binds all of them into tcl, in the said package, which
> is passed as the first parameter to the bind_perl_to_tcl_commands method.
> 
> An example:
> 
> use Tcl;
> 
> my $int = new Tcl;
> 
> $int->bind_perl_to_tcl_commands;
> 
> $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
> pack .b1 .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";
> }
> 
> =cut
> 
> sub bind_perl_to_tcl_commands {
>    my $int = shift;
> 
>    # name of Tcl package to hold tcl commands bound to perl subroutines
>    my $tcl_namespace = shift || 'perl';
> 
>    # name of Perl package, which subroutines would be bound to tcl commands
>    my $perl_namespace = shift || 'tcl';
> 
>    die "Shouldn't bind to main package"
>        if $perl_namespace eq "" || $perl_namespace eq "main";
> 
>    for my $subname (keys %{"$perl_namespace\::"}) {
>       # have no need to check if this is a sub name or a var name, as long
>       # as we're binding to CODE, \&{"..."}
>       
> $int->CreateCommand("$tcl_namespace\::$subname",\&{"$perl_namespace\::$subname"});
>    }
> }
> 
> 
> Similar binding of variables could also be added.
> 
> Best regards,
> Vadim.

Reply via email to