Thread: RE: [tcltk-perl] Drop listify [PATCH]
Brought to you by:
hobbs
From: Konovalov, V. <vko...@sp...> - 2004-04-14 12:48:23
|
To be honest, I did not tried that Jeff's subroutine yet, but why do you think it should not be included? AFAIU it is used in perlTk compatibility widgets implementation. > This patch seems like a good idea to me. > > --Gisle > > > Index: Tcl.pm > =================================================================== > RCS file: /cvsroot/tcltkce/Tcl/Tcl.pm,v > retrieving revision 1.9 > diff -u -p -u -r1.9 Tcl.pm > --- Tcl.pm 12 Apr 2004 23:09:56 -0000 1.9 > +++ Tcl.pm 14 Apr 2004 09:18:45 -0000 > @@ -302,28 +302,6 @@ sub LINK_READ_ONLY () { 0x80 } > > bootstrap Tcl; > > -# This is a crude list-creating routine. 'icall' convert perl array > -# refs into Tcl list objects efficiently, so this isn't necessary. > -# It is also not "comprehensive", so should be used as a last resort. > -sub listify { > - my $res; > - for my $arg (@_) { > - my $ref = ref($arg); > - $res .= " " if $res; > - if (!$ref && $arg =~ / /) { > - $res .= "{$arg}"; > - } > - elsif ($ref eq "ARRAY") { > - $res .= "{" . listify(@$arg) . "}"; > - } > - else { > - $arg =~ s/\\/\\\\/g; > - $res .= $arg; > - } > - } > - return $res; > -} > - > #TODO make better wording here > # %anon_refs keeps track of anonymous subroutines that were > created with > # "CreateComand" method during process of transformation of > arguments for > @@ -386,12 +364,6 @@ sub call { > # XXX needs testing > $args[$argcnt] = > $interp->create_tcl_sub(sub > {$arg->[0]->(@$arg[1..$#$arg])}); > - } > - else { > - # Do nothing here, as icall recurses into ARRAYs and > - # turns them into true Tcl lists > - # Should properly turn ARRAY into Tcl list > - #$args[$argcnt] = listify(@$arg); > } > } > } > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > Tcltk-perl mailing list > Tcl...@li... > https://lists.sourceforge.net/lists/listinfo/tcltk-perl > |
From: Konovalov, V. <vko...@sp...> - 2004-04-14 13:54:57
|
> > For sure we need an addition in test files to check > handling array refs. > > It looks like the tests could need more work in other areas too. I'll > try to contribute some to it in the days ahead. that would be nive, thanks! |
From: Konovalov, V. <vko...@sp...> - 2004-04-14 13:17:02
|
> > To be honest, I did not tried that Jeff's subroutine yet, > but why do you > > think it should not be included? > > Because it is dead code which i not needed. Also the 'it is also not > "comprehensive"' make me think it is actually buggy. Now I see. Looks like Jeff implemented it in Tcl.xs, so it is not needed indeed. For sure we need an addition in test files to check handling array refs. Vadim. |
From: Gisle A. <gi...@Ac...> - 2004-04-14 13:19:51
|
"Konovalov, Vadim" <vko...@sp...> writes: > For sure we need an addition in test files to check handling array refs. It looks like the tests could need more work in other areas too. I'll try to contribute some to it in the days ahead. --Gisle |
From: Konovalov, V. <vko...@sp...> - 2004-04-15 05:36:36
|
> OK, I think the real problem was the bit of code at the end of > 'call' that conflicted with Tcl.xs:prepare_Tcl_result() which > handled the G_SCALAR / G_ARRAY diffs already. I think the > following patch is appropriate, and it works with a call.t that > I just checked into CVS. Please comment on this, as I am not > certain that I'm not breaking some perl basic assumptions here. I see new code as good improvements of elder one. However I have few ideas to this bit of code, and I have them implemented in my local machine: 1. it could be reasonable to sometimes make reverse subtitution of parameters after getting result of Tcl calculation. May be in subroutine with slightly different name (wcall?) it is needed for, say, $widget->cget('-textvariable') to return a reference scalar and not a name like _SCALAR_0xXXXXXX Very correct way is not obvious to me, but half-correct way is to create another wrapper layer subroutine wcall that will search content of $res (and @res?) in %anon_refs hash. 2. I see it very useful for DEBUGging purposes to have a possibility to track what exactly list passed to "icall" and what returned from it. This helps in developing perlTk compatibility subroutines... > > Index: Tcl.pm > =================================================================== > RCS file: /cvsroot/tcltkce/Tcl/Tcl.pm,v > retrieving revision 1.9 > diff -u -r1.9 Tcl.pm > --- Tcl.pm 12 Apr 2004 23:09:56 -0000 1.9 > +++ Tcl.pm 14 Apr 2004 18:33:09 -0000 > @@ -395,15 +395,23 @@ > } > } > } > - my (@res,$res); > - eval { > - @res = $interp->icall(@args); > - }; > - if ($@) { > - confess "Tcl error $@ while invoking call\n \"@args\""; > + if (wantarray) { > + my @res; > + eval { @res = $interp->icall(@args); }; > + if ($@) { > + confess "Tcl error '$@' while invoking array > result call:\n" . > + "\t\"@args\""; > + } > + return @res; > + } else { > + my $res; > + eval { $res = $interp->icall(@args); }; > + if ($@) { > + confess "Tcl error '$@' while invoking scalar > result call:\n" . > + "\t\"@args\""; > + } > + return $res; > } > - return @res if wantarray; > - return $res[0]; > } > > > Jeff > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: IBM Linux Tutorials > Free Linux tutorial presented by Daniel Robbins, President and CEO of > GenToo technologies. Learn everything from fundamentals to system > administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click > _______________________________________________ > Tcltk-perl mailing list > Tcl...@li... > https://lists.sourceforge.net/lists/listinfo/tcltk-perl > |
From: Jeff H. <je...@Ac...> - 2004-04-15 20:53:15
|
> 1. it could be reasonable to sometimes make reverse > subtitution of parameters after getting result of Tcl > calculation. May be in subroutine with slightly different > name (wcall?) > > it is needed for, say, $widget->cget('-textvariable') to > return a reference scalar and not a name like _SCALAR_0xXXXXXX > > Very correct way is not obvious to me, but half-correct way > is to create another wrapper layer subroutine wcall that will > search content of $res (and @res?) in %anon_refs hash. Yes, it would be nice to be able to round trip these values better. I think the first run would be to clean up how the module creates commands and vars in Tcl (use a ::perl namespace, where we can also create our own stuff like ::perl::eval). Later on we could look into creating our own object type in Tcl to wrap Perl SVs, so we never lose touch either way. > 2. I see it very useful for DEBUGging purposes to have a > possibility to track what exactly list passed to "icall" and > what returned from it. This helps in developing perlTk > compatibility subroutines... This is just another couple of print statements cased on DEBUG, no? Jeff |
From: Konovalov, V. <vko...@sp...> - 2004-04-16 05:43:16
|
> > 1. it could be reasonable to sometimes make reverse > > subtitution of parameters after getting result of Tcl > > calculation. May be in subroutine with slightly different > > name (wcall?) > > > > it is needed for, say, $widget->cget('-textvariable') to > > return a reference scalar and not a name like _SCALAR_0xXXXXXX > > > Yes, it would be nice to be able to round trip these > values better. I think the first run would be to clean > up how the module creates commands and vars in Tcl (use > a ::perl namespace, where we can also create our own > stuff like ::perl::eval). Later on we could look into this looks like this is robust enough way... > creating our own object type in Tcl to wrap Perl SVs, so > we never lose touch either way. but in this case we'll lose compatibility with current version of Tcl/Tk, 8.4.x, which do not have such object type... > > 2. I see it very useful for DEBUGging purposes to have a > > possibility to track what exactly list passed to "icall" and > > what returned from it. This helps in developing perlTk > > compatibility subroutines... > > This is just another couple of print statements cased on > DEBUG, no? yes, only that, and I, while I use those, I did not even inserted those into CVS because those are so easy and obvious, so anyone who needs them just add "print" statements and go... Best regards, Vadim. |
From: Jeff H. <je...@Ac...> - 2004-04-16 17:27:55
|
> > creating our own object type in Tcl to wrap Perl SVs, so > > we never lose touch either way. > > but in this case we'll lose compatibility with current > version of Tcl/Tk, 8.4.x, which do not have such object type... I think you misread. Let me rephrase ... we can create our own Tcl object type to wrap Perl SVs. No compatability will be lost. Jeff |
From: Vadim K. <va...@ar...> - 2004-04-16 18:00:37
|
> > > creating our own object type in Tcl to wrap Perl SVs, so > > > we never lose touch either way. > > > > but in this case we'll lose compatibility with current > > version of Tcl/Tk, 8.4.x, which do not have such object type... > > I think you misread. Let me rephrase ... we can create our > own Tcl object type to wrap Perl SVs. No compatability will > be lost. I did not realized that it is possible to create new Tcl object type outside Tcl (in extension), but now I realize this could be quite possible. And looks like most correct way to go... Vadim. |
From: Jeff H. <je...@Ac...> - 2004-04-16 18:05:44
|
> > I think you misread. Let me rephrase ... we can create our own Tcl > > object type to wrap Perl SVs. No compatability will be lost. > > I did not realized that it is possible to create new Tcl > object type outside Tcl (in extension), but now I realize > this could be quite possible. And looks like most correct way to go... It is indeed possible, and this is what TclBlend does (the Tcl/Java interface) to keep Java objects wrapped. Jeff |
From: Vadim K. <va...@ar...> - 2004-04-17 05:23:11
|
Dear Jeff, I've noticed you made t/info.t to pass on Win32. However I did it too, but from different side: --- D:\Personal\cvsroot\Tcl\t\info.t Thu Apr 15 15:01:07 2004 +++ D:\Personal\perl-CPAN\Tcl\t\info.t Sat Apr 17 00:44:19 2004 @@ -7,11 +7,12 @@ use Tcl; use Sys::Hostname qw(hostname); +use File::Spec::Functions; my $tcl = Tcl->new; ok($tcl); -ok($tcl->Eval("info nameofexecutable"), $^X); +ok(canonpath($tcl->Eval("info nameofexecutable")), canonpath($^X)); ok($tcl->Eval("info hostname"), hostname); my $tclversion = $tcl->Eval("info tclversion"); ===== Do you mind if I'll insert mine, because it does not rely on $^O so will probably pass cleanly on other weird file systems? Best regards, Vadim. |
From: Jeff H. <je...@Ac...> - 2004-04-17 06:08:14
|
Vadim Konovalov wrote: > Do you mind if I'll insert mine, because it does not rely on $^O so will > probably pass cleanly on other weird file systems? Sounds fine to me. |
From: Vadim K. <va...@ar...> - 2004-04-17 07:48:37
|
Dear all! I did Tcl-0.76 CPAN release (see below) and I am going to do Tcl-Tk-0.77 release. However, when doing Tcl::Tk changes, I realised that I forgot to include a wrapper function "wcall" to Tcl.pm, which is needed for t/Optionmenu.t wcall is wrapper for "call" that tries to find its result in %anon-hash What is your wise advice in this situation? Do another 'Tcl' CPAN release with small addition right now? Version 0.77? (will match with Tcl::Tk version BTW) Comment out t/Optionmenu.t in Tcl-Tk and wait for robust implementation via special Tcl object wrapper for SV, as Jeff mentioned? Best regards, Vadim. ======================= The uploaded file Tcl-0.76.tar.gz has entered CPAN as file: $CPAN/authors/id/V/VK/VKON/Tcl-0.76.tar.gz size: 20418 bytes md5: 01438df55b65f5ec2075548421311b1d No action is required on your part Request entered by: VKON (Vadim Konovalov) Request entered on: Sat, 17 Apr 2004 07:03:21 GMT Request completed: Sat, 17 Apr 2004 07:03:50 GMT Thanks, -- paused, v460 |
From: Gisle A. <gi...@Ac...> - 2004-04-17 08:24:45
|
"Vadim Konovalov" <va...@ar...> writes: > Dear all! > > I did Tcl-0.76 CPAN release (see below) and I am going to do Tcl-Tk-0.77 > release. > > However, when doing Tcl::Tk changes, I realised that I forgot to include a > wrapper function "wcall" to Tcl.pm, which is needed for t/Optionmenu.t > > wcall is wrapper for "call" that tries to find its result in %anon-hash > > What is your wise advice in this situation? > > Do another 'Tcl' CPAN release with small addition right now? Version 0.77? > (will match with Tcl::Tk version BTW) Yes. There is no reason to not update a CPAN release right away if you discover there is something wrong about it. --Gisle |
From: Vadim K. <va...@ar...> - 2004-04-17 08:41:04
|
> Yes. There is no reason to not update a CPAN release right away if > you discover there is something wrong about it. Ok, thanks. BTW I'm doing rather deep changes into Tk.pm: - all widgets (Baloon, Menu, ...) will live in their own package, just like Label, Button, Frame. - special_widget_abilities replaced just to creating subroutines in said widget's packages - remove %scrolls hash away. Probably code will be less in size and more consistent. Best regards, Vadim. |
From: Vadim K. <va...@ar...> - 2004-04-17 08:54:47
|
> > Yes. There is no reason to not update a CPAN release right away if > > you discover there is something wrong about it. > > Ok, thanks. false alarm: $widget->cget('-textvariable') for 'Optionmenu' is implemented as Tcl::Tk::MultipleWidget and that call is intercepted differently, right now I will not touch CPAN version of Tcl. Sorry for bothering. Best regards, Vadim. |
From: Vadim K. <va...@ar...> - 2004-04-17 11:42:19
|
> false alarm: > > $widget->cget('-textvariable') for 'Optionmenu' is implemented as > Tcl::Tk::MultipleWidget and that call is intercepted differently, right now > I will not touch CPAN version of Tcl. However there is another problem: for some reason invoking $widget->grid(-column=>1) results in transformation of 1 to 1.0 and grid packer gives an error. Stringifying that "1" helps in this, but problem persists. I made another release right now, and add test for this case later. Best regards, Vadim. |
From: Jeff H. <je...@Ac...> - 2004-04-17 19:38:35
|
Vadim Konovalov wrote: > However there is another problem: for some reason invoking > $widget->grid(-column=>1) > results in transformation of 1 to 1.0 and grid packer gives an error. > > Stringifying that "1" helps in this, but problem persists. This will be due to checking SvNOK before SvIOK in TclObjFromSv. However ... that should work correctly regardless, as grid should be able to request the int from a Tcl_DoubleObj. I will have to look into this further. -- Jeff Hobbs, The Tcl Guy http://www.ActiveState.com/, a division of Sophos |
From: Jeff H. <je...@Ac...> - 2004-04-17 17:30:51
|
Vadim Konovalov wrote: > However, when doing Tcl::Tk changes, I realised that I forgot to include a > wrapper function "wcall" to Tcl.pm, which is needed for t/Optionmenu.t ... > Do another 'Tcl' CPAN release with small addition right now? Version 0.77? > (will match with Tcl::Tk version BTW) Just add it in. We aren't at a shortage of numbers ;). Jeff |
From: Vadim K. <va...@ar...> - 2004-04-17 19:18:57
|
> > Do another 'Tcl' CPAN release with small addition right now? Version 0.77? > > (will match with Tcl::Tk version BTW) > > Just add it in. We aren't at a shortage of numbers ;). I noticed a typo in Tcl-Tk-0.77 after releasing to CPAN, now corrected in CVS. I suppose typo is not critical, so no need to hurry doing next release. Best regards, Vadim. |
From: Gisle A. <gi...@Ac...> - 2004-04-14 13:04:40
|
"Konovalov, Vadim" <vko...@sp...> writes: > To be honest, I did not tried that Jeff's subroutine yet, but why do you > think it should not be included? Because it is dead code which i not needed. Also the 'it is also not "comprehensive"' make me think it is actually buggy. > AFAIU it is used in perlTk compatibility widgets implementation. I did not find any reference to this function in the Tcl-Tk module either. --Gisle |
From: Jeff H. <je...@Ac...> - 2004-04-14 16:59:39
|
> "Konovalov, Vadim" <vko...@sp...> writes: > > To be honest, I did not tried that Jeff's subroutine yet, but why do > > you think it should not be included? > > Because it is dead code which i not needed. Also the 'it is > also not "comprehensive"' make me think it is actually buggy. That is correct, it is buggy (given certain input, it will not produce a 100% correct list), and it isn't used anywhere at the moment. The xs changes I made alleviate the need - for now. This touches on stuff that I think requires rethinking in the whole Tcl module - array/list handling. The SvFromTclObj and TclObjFromSv procedures that I added allow for the efficient transformation of data at the object level between Perl and Tcl. An SvIV becomes a Tcl int object and vice versa. What is not completely round-tripped are Tcl lists, but an AV will become a pure Tcl list. You can see the part in SvFromTclObj where I try to create an AV back from a Tcl list. The problem with this is that we then return an array reference, and I think it's complicated by the code in Tcl.xs:prepare_Tcl_result that handles G_SCALAR and G_ARRAY differently, in addition to the code in Tcl.pm:call() that does at the end: return @res if wantarray; return $res[0]; Let's make some concrete examples. Here is a code block: use Tcl; my $interp = Tcl->new; my $lres = $interp->Eval("set var [list a b c]"); #1 my $sres = $interp->Eval("set var {a b c}"); #2 my (@lares) = $interp->Eval("set var [list a b c]"); #3 my (@sares) = $interp->Eval("set var {a b c}"); #4 print STDOUT "list: ", $lres, "\n"; print STDOUT "string: ", $sres, "\n"; print STDOUT "litems: ", $_, "\n" for (@lares); print STDOUT "sitems: ", $_, "\n" for (@sares); This will currently work "as expected" whether we get a true (pure) list back from Tcl, or a string that can be broken into a list. #1 returns a Tcl_Obj of tclListType, whereas #2 returns just a string (NULL object type). For a small list, the time difference is negligible, but for 1000 items lists, we should really be treating it right. The results with current code are: list: a b c string: a b c litems: a litems: b litems: c sitems: a sitems: b sitems: c If you flip on the tclListType conversion (to AV ref) in SvFromTclObj (there is a #if there), you instead get: list: ARRAY(0x191ea5c) string: a b c litems: a litems: b litems: c sitems: a sitems: b sitems: c and I believe that this may lead to problems (it broke an app that I was converting from pTk code) where I had this: my $themes = $interp->Eval("style theme names"); OK, so I really should have this: my (@themes) = $interp->Eval("style theme names"); but I think making the change leads to issues that force users to think more about the return value. The above code returns a pure Tcl list - but the coder could have been lazy and created a list-like string instead (as many people still do), and it would all work. Am I wrong in thinking that users should be forced to code properly (whether they expect list/array or string/scalar) in the first place? I'm also unsure about both $interp->icall and $interp->call behavior handling G_ARRAY and G_SCALAR differently. See this difference (this behaves the same whether you do the pure list conversion or not): my $res = $interp->call('set', 'var', 'a b c'); my $ires = $interp->icall('set', 'var', 'a b c'); my @ares = $interp->call('set', 'var', 'a b c'); my @iares = $interp->icall('set', 'var', 'a b c'); print STDOUT "call: ", $res, "\n"; print STDOUT "icall: ", $ires, "\n"; print STDOUT "lcall: ", $_, "\n" for (@ares); print STDOUT "licall: ", $_, "\n" for (@iares); outputs: call: a icall: a b c lcall: a lcall: b lcall: c licall: a licall: b licall: c but I guess that's an expectation for Perl users (for $res to grab first element of a list), but when I change to pure list form in calling convention and use tclListType conversion with: my @list = $interp->icall('list', 'a', 'b', 'c'); my $res = $interp->call('set', 'var', [@list]); my $ires = $interp->icall('set', 'var', [@list]); my @ares = $interp->call('set', 'var', [@list]); my @iares = $interp->icall('set', 'var', [@list]); print STDOUT "call: ", $res, "\n"; print STDOUT "icall: ", $ires, "\n"; print STDOUT "lcall: ", $_, "\n" for (@ares); print STDOUT "licall: ", $_, "\n" for (@iares); I get: call: a icall: ARRAY(0x191e9ec) lcall: a lcall: b lcall: c licall: a licall: b licall: c again, basically same as above. Is this something that won't surprise Perl users? Jeff |
From: Jeff H. <je...@ac...> - 2004-04-14 18:43:02
|
> You can see the part in SvFromTclObj where I try to create an > AV back from a Tcl list. The problem with this is that we > then return an array reference, and I think it's complicated > by the code in Tcl.xs:prepare_Tcl_result that handles > G_SCALAR and G_ARRAY differently, in addition to the code in > Tcl.pm:call() that does at the end: > > return @res if wantarray; > return $res[0]; OK, I think the real problem was the bit of code at the end of 'call' that conflicted with Tcl.xs:prepare_Tcl_result() which handled the G_SCALAR / G_ARRAY diffs already. I think the following patch is appropriate, and it works with a call.t that I just checked into CVS. Please comment on this, as I am not certain that I'm not breaking some perl basic assumptions here. Index: Tcl.pm =================================================================== RCS file: /cvsroot/tcltkce/Tcl/Tcl.pm,v retrieving revision 1.9 diff -u -r1.9 Tcl.pm --- Tcl.pm 12 Apr 2004 23:09:56 -0000 1.9 +++ Tcl.pm 14 Apr 2004 18:33:09 -0000 @@ -395,15 +395,23 @@ } } } - my (@res,$res); - eval { - @res = $interp->icall(@args); - }; - if ($@) { - confess "Tcl error $@ while invoking call\n \"@args\""; + if (wantarray) { + my @res; + eval { @res = $interp->icall(@args); }; + if ($@) { + confess "Tcl error '$@' while invoking array result call:\n" . + "\t\"@args\""; + } + return @res; + } else { + my $res; + eval { $res = $interp->icall(@args); }; + if ($@) { + confess "Tcl error '$@' while invoking scalar result call:\n" . + "\t\"@args\""; + } + return $res; } - return @res if wantarray; - return $res[0]; } Jeff |
From: Jeff H. <je...@Ac...> - 2004-04-14 21:47:51
|
> OK, I think the real problem was the bit of code at the end > of 'call' that conflicted with Tcl.xs:prepare_Tcl_result() > which handled the G_SCALAR / G_ARRAY diffs already. I think > the following patch is appropriate, and it works with a > call.t that I just checked into CVS. Please comment on this, > as I am not certain that I'm not breaking some perl basic > assumptions here. I have gone ahead and commited changes that turn on the Tcl_ListObj -> AV and rewritten 'call' based on my earlier patch. Tests are all still successful. Jeff |
From: Gisle A. <gi...@Ac...> - 2004-04-15 15:18:08
|
Is there a semantic difference between [list a b c] and {a b c} in Tcl the language? If not, then I don't think they should be different when passed to perl either. --Gisle |