Okay I agree that showing some code would make the point more convincing and I have plan to try it. Let's stop the discussion.
SJ 2018-07-14 12:43 GMT+08:00 huck <h...@finn.com>: > At 08:50 PM 7/13/2018, you wrote: >> >> <URL: https://rt.cpan.org/Ticket/Display.html?id=125472 > >> >> 2018-07-07 22:46 GMT+08:00 huck : >> >> > >> > Yes, as we saw when code disposal was introduced , even existing >> > applications can be ruined if care is not properly taken. Maybe if >> > create_tcl_sub() had been documented as part of the api this problem >> > would >> > not have been created in the first place. >> > >> >> I think it had not been because create_tcl_sub() was created for >> internal use only and not intended to be an API. > > > Maybe if it had been documented the original code disposal changes would not > have busted existing programs like they did. > > I also find it hard to believe that just because something was one designed > for internal use it means it can never be exposed as part of the API. > > create_tcl_sub() is now integral to the code disposal changes. It is the > place that code disposal is now controled. allowing external access to it is > basically the only way to allow the developer to control code disposal. > > > >> > >> >> >> >> My idea is to apply a prefix to identify if first argument of call() is >> >> a >> >> DESCRNAME. If the first arg call() is '%' , then it is a DESCRNAME. >> >> (Let's >> >> forget previous AT sign '@' example, which might confuse you). >> >> Otherwise the >> >> first arg is a tcl verb. For example the following code: >> >> >> >> call('%button1', ..., $sub1, sub{}) >> >> call('%button1', ..., $sub2, $sub3) >> >> call('if', '1', $sub3) >> >> : >> >> code_dispose('button1'); >> >> >> >> Then inline sub{}, $sub1 and $sub2 would get disposed while #sub3 is >> >> kept. >> >> The code looks much cleaner compared to annoying TCLNAME/GENCODE/EVENT >> >> dealing and storing. Here one DESCRNAME maps to multiple $subs, which >> >> is not >> >> allowed in current implementation. Just share an idea for a better >> >> disposal >> >> interface. >> > >> > >> > >> > And how would you implement this via Tkx? >> > for instance how do you modify a $menu>add_command(%args); call? >> > or $button =$in->new_ttk__button(-text=>$args{text}, >> > -command=>$args{sub} ); >> > >> >> It's not for Tkx user. It's for Tcl user (such as Tkx). Tkx can >> associate a unique DESCRNAME 'menu1' with an object $menu and call >> code_dispose('menu1') on destroyer of $button1. > > > Ya know i dont care much about the Tcl only user. I use it from Tkx, > somebody busted tkx. i fixed it. QED. > > Who is going to make the changes to Tkx to do this? How do i pass this > information from my program to tkx to do it? Right now tkx is a simple > intercept interface between perl and ttk. Basically a tkx developer does > not interface with call() at all. How do you propose they do it under your > scenario? > > My WORKING solution allows the tkx user to get access to code disposal via > create_tcl_sub(). I dont hear any solutions from you , just proposals. > > And what destroyer of $button1 are you talking about? can you show me where > Tkx sets up a destroyer for a button? Or are you proposing that someone come > up with the new code? Are you going to do it? > > tkx just recodes a perl call into the corresponding tk name and calls that > tk procedure. > >> In previous example, $sub1, inline sub{}, $sub2 get disposed when >> code_dispose('button1') is called. They get disposed because they are >> associated with DESCRNAME 'button1' via call('%button1'). $sub3 is >> also associated with 'button1', it does not get disposed because it >> has also been call()'ed once without DESCRNAME. > > > > It is never called without a DESCRNAME, call() always assigns a DESCRNAME > when it calls create_tcl_sub(), i think your proposal to add a leading > argument to call() has not been well thought out yet. The arguments to > call() are very well defined now, they constitute the elements of a call to > tcl, now you want to majorly modify what the arguments are for no good > reason i can figure out so far. > > > >> > like you said before if you dont know what to do with EVENT it can be >> > defined as undef, and then TCLNAME is the same as GENCODE (as the doc >> > says) >> > and only that one item needs to be saved, just like you need to save the >> > CMDNAME passed to CreateCommand () >> > >> > Changing the existing and working interface to call() seems to be much >> > more >> > error prone than documenting the interface to create_tcl_sub(), just >> > making >> > things more complex. >> > >> > As i already mentioned by using create_tcl_sub() to manage code >> > disposal, i >> > can just add one call to create_tcl_sub() to lock down a sub from code >> > disposal, and add another call to _code_destroy() when i want to release >> > that coderef. Your proposed method requires every call with a coderef >> > to be >> > modified which was one thing i was trying to avoid. >> > >> > And you say "would get disposed", but when? the only time code may get >> > automagicly disposed is when something has the same DESCRNAME, but here >> > you >> > propose allowing DESCRNAME ot have the same value over multiple calls, >> > are >> > you proposing that inside the second call $sub1 and sub{}) get >> > disposed? >> > or are you proposing that $sub3 gets added to that list for disposal >> > later? >> > >> > And a DESCRNAME can have more than one sub attached to it since v1.06 >> > What >> > it is is that when the same DESCRNAME is seen again, the prior code >> > calls >> > are now eligible for code destruction. One change i made is to delay >> > code >> > destuction untill after the entire command is parsed, so as not to have >> > to >> > destroy/recreate a coderef that already exists in both the current and >> > the >> > prior call with the same DESCRNAME This wasnt a problem at v1.02 because >> > %anon_refs was only assigned to if the TCLNAME did not exist already >> > >> >> >> BTW, I found _code_dispose() has to be called in the form >> >> 'Tcl::_code_dispose(...)' rather than '$interp->_code_dispose(...)'. It >> >> is >> >> documented, but it is counter-intuitive. Programmers can hardly find >> >> their >> >> incorrect calling via $interp object. I suggest to check input >> >> parameter and >> >> provide some warning at least. IMO, %anon_refs{} would be better an >> >> object >> >> instance variable instead of global one. >> > >> > >> > >> > but it isnt an object instance now, as far as i can tell never has been, >> > So >> > the change you are proposing here is not trivial. What should it be an >> > instance of? >> > >> > While $interp can be considered an object all it is really is a blessed >> > scalar. So where do you propose you store this new object instance? If >> > we >> > make $interp be the first key to %anon_refs that will cause a lot of >> > code to >> > need to be changed. >> > >> > And as i pointed out while delete_ref() is called with an $interp for >> > the >> > most part that doesnt matter, since the $interp stored in the Tcl::Code >> > object is used for the deletion, and while there could be many different >> > interpreters, there is only one %anon_refs, so that on a single TCLNAME >> > can >> > exist, there cannot be one for each interpreter. >> >> I mean %anon_refs shall be better to be something like >> $interp->{anon_refs}. Different interpreters shall be better have >> separated TCLNAME/CMDNAME/DESCRNAME naming space. It does not make >> sense that TCLNAME/DESCRNAME have to be unique across different >> interpreters. > > > It is not that way now, and as far as i can tell it was never that way ever. > What you are asking for is not a simple change to make,. it changes a lot of > things. > > my $inter=Tcl->new(); print Dumper($inter); > $VAR1 = bless( do{\(my $o = 149405600)}, 'Tcl' ); > > there is no place for $interp->{anon_refs} to live. it is just a blessed > scalar. > > Have you even looked at the code at all yet? > > >> > Again, maybe the solution is to make a RFP asking for input on code >> > disposal, what it should do, how it should be called and what >> > modification >> > will be needed to existing code. Without that my intentions were to make >> > it >> > so existing v1.02 code still worked, and there was a mechanism to >> > control >> > code disposal. I think my patches have met both of those goals. (and as >> > i >> > watched code disposal in action i realized it was destroying/recreating >> > tcl >> > subs over and over and i wanted to prevent that too) >> > >> > and i also realized that a deep bug in the xs code was leading to a >> > massive >> > memory leak and fixed that as well. >> >> Yes I believe v1.06 got quite some bugs fixed. Here just some >> discussion for any possibility to make interface more clean. > > > Yes my fixes have made v1.11 working again. All is working at least like it > used to and there is elementary code disposal for 'after' calls like > intorduced after v1.02. > > All i see is trying to make the interface more complicated, without > proposing any code changes yourself. You want to change what $inter is, from > a blessed scalar to a blessed hash. you want to change how call() is > defined, yoiu are proposing major changes to tkx.pm that will complicate it > by introducing some sort of interface between all the perl and tcl calls > that will create destroyers. > > So are you proposing to pay me to do all this or are you going to do it > yourself? > > I think the easiest thing here is for you to make your own branch and put in > the changes you want, show me the working code that passes all the tests. > Then explain how it is cleaner, and why it is any better than what we have > now. I have no desire to do something just because you want it done. > > I wanted to get my tkx programs working again, i put the time in to make it > so, and i think i did a much better job than what you have proposed so far. > It you can do better than go right ahead. > > My proposal for you is to start with a statement of what you want code > disposal to do. then describe how you will modify tcl.pm to do that, then > describe how you will modify tkx.pm to incorporate that path. Once you have > reached that point publish your proposal and see what comments you get back. > > Then you can go in and study v1.02 and v1.05 and see what changed, once you > have reached that point you can start making the improvements to the code. > Then you can publish a patch so we can install it to a local branch and see > how it works. > > Again, my purpose when I took on this task to make tcl better than it was > because for no fault of mine my programs stopped working. I spent a lot of > time looking thru the code and learning how to think like the authors did > when they wrote their code. The change from v1.02 to v1.05 was not minor, > It changed a lot of how %anon_refs was used. My fix incorporates the > original design of %anon_refs tracking the TCLNAME so it doenst constantly > redefine perl <->tcl coderefs, it also tracks the new DESCRNAME used for > code disposal purposes, I does not redefine a TCLNAME that currently exists, > and only destroys it when all the registered users of that TCLNAME have been > eliminated. I joined the original v1.02 and the v1.05 code in a way that > satisfies the purposes of both of them > > It requires no changes to existing tcl/tkx programs or to tkx.pm to work > properly. > > It also allows for developer access to this code disposal procedure via > create_tcl_sub() so they can have a say in how code disposal works for them. > >> SJ