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.

>
>>
>> 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.

   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.

> 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.

> 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.

SJ

Reply via email to