From: fips on
On 10 Mrz., 12:50, Koen Danckaert <k...(a)spam.spam> wrote:
> fips wrote:
> > On 10 Mrz., 10:55, "dave.joub...(a)googlemail.com"
> > <dave.joub...(a)googlemail.com> wrote:
> >>> I would like to use methods on objects like this:
> >>> - set obj1 [obj2 method ?args?]
> >>> where the method "method" called on object "obj2" creates an object
> >>> that is bound to the caller object "obj1". No objects created in
> >>> "method" should exist after the call, and the object created in
> >>> "method" (or the object's value) should be passed to the calling
> >>> object "obj1".
> >> The way I do it is when I create the new object within the called
> >> method, is I create it in the caller's frame (or toplevel) not the
> >> called frame.
> >> That solves all my problems. (I use iTcl)
>
> >> Dave
>
> > The point is that there is a "simple way" to do this in ITcl and I am
> > searching for an XOTcl equivalent:
> > In ITcl I would do this:
>
> >     public method + { aComplex } {
>
> >            set resultReal [expr { $real + [$aComplex getReal] }]
> >            set resultImag [expr { $imag + [$aComplex getImag] }]
> >            set result [Complex #auto $resultReal $resultImag]
> >            return $result
> >     }
>
> > The line "set result [Complex #auto $resultReal $resultImag]" creates
> > exactly the kind of object I need (specifier #auto) and then "return
> > $result" returns the value of the object. This value can then be used
> > by the method's caller.
>
> You are confusing things here. Both IncrTcl and XOTcl always refer to objects by their name and not by their value. The "#auto" specifier simply selects a unique name. It has nothing to do with automatic cleanup.
>
> In XOTcl you can use the [new] method to achieve what you want:
>
>   set result [Complex new $resultReal $resultImag]
>   return $result
>
> --Koen

Ok, maybe you are right on the meaning of "#auto". That would mean
that the mentioned "deallocation-passing" problem would also exist
with ITcl.
From: dave.joubert on
On Mar 10, 12:44 pm, fips <filiberto.silves...(a)hotmail.de> wrote:

>
> The use of complex numbers is just an example.

You also wrote earlier:
> The point is that I would like to create objects in methods without creating "garbage".

OK, but as a general rule, if you are going to have methods that
create objects, then you should create the objects somewhere
predictable (where you know that you can get at them (irrespective of
which object framework you end up using)).

A) creating them in the called frame in useless, because as you can
see, they 'disappear'
B) creating them in the caller [uplevel] frame forces you to remember
to in turn pass them back up if the call is indirect
C) creating them in the global namespace is messy

Dave
From: Donal K. Fellows on
On 9 Mar, 17:28, fips <filiberto.silves...(a)hotmail.de> wrote:
> The problem here with the object "result" is that it is still
> there after method conclusion.

Yes. The issue is simply that Tcl doesn't do Garbage Collection of
commands[*], and Tcl objects are always commands. There *are* several
ways to fake it. Nasty ways. (For example, the -volatile option you
mention is using an unset trace on a local variable. It's fine if
you're going to follow the RAII model, but there are other models -
[uplevel] is a great thing - that feel even more natural in Tcl.)

Donal.
[* Strictly, it doesn't do that for values either, but Tcl's value
system doesn't need it and so reference counting - which is used -
works just fine. ]
From: Donal K. Fellows on
On 10 Mar, 08:26, fips <filiberto.silves...(a)hotmail.de> wrote:
> Certainly, XOTcl is more "dynamic" than ITcl. And the question I posed
> to myself is: will we ever need all this?

One advantage of going to a more powerful system is that it allows
features that *are* interesting to be written more simply. For
example, object serialization (and, more to the point,
deserialization) is something that's simple enough in a system with
XOTcl's power, but where Itcl's restrictions become more of an issue.
It's only an example, of course, but even so.

For my money, I'd say that you should go with the one that feels more
natural to you. Trying both out won't take very long and both are well-
supported with communities of users.

Donal.
From: fips on
On 10 Mrz., 14:30, "Donal K. Fellows"
<donal.k.fell...(a)manchester.ac.uk> wrote:
> On 9 Mar, 17:28, fips <filiberto.silves...(a)hotmail.de> wrote:
>
> > The problem here with the object "result" is that it is still
> > there after method conclusion.
>
> Yes. The issue is simply that Tcl doesn't do Garbage Collection of
> commands[*], and Tcl objects are always commands. There *are* several
> ways to fake it. Nasty ways. (For example, the -volatile option you
> mention is using an unset trace on a local variable. It's fine if
> you're going to follow the RAII model, but there are other models -
> [uplevel] is a great thing - that feel even more natural in Tcl.)
>
> Donal.
> [* Strictly, it doesn't do that for values either, but Tcl's value
> system doesn't need it and so reference counting - which is used -
> works just fine. ]

Maybe I found a solution to the object deletion/passing problem that
would be quite satisfactory for me.
The idea is, as proposed by some in the ng here, to "store" objects
created by methods where they can easily be found and deleted as
needed. I thought about storing them as child objects in their
classes.
The following code fragment shows this:

# Method "add".
Complex instproc add { aComplex } {

my instvar real imag
set resultReal [expr { $real + [$aComplex set real] }]
set resultImag [expr { $imag + [$aComplex set imag] }]
eval Complex new -childof Complex $resultReal $resultImag
}

The method "add" is rewritten with the following changes:
- the "new" function assigns a unique name to the object
- the object is stored as child of its class

A garbage collector functions which iterates through classes and
cleans them up could be as follows:

# Garbage collector.
# Deletes temporary objects created in method calls.
proc gc {} {

# Iterate on all classes.
foreach class_ [Class info instances] {

# Skip system classes.
if { $class_ == "::__unknown" || [string first "::xotcl" $class_] !=
-1 } {
continue
}

# Cleaup user defined class by deleting all its children.
foreach child [$class_ info children] {
$child destroy
}
}
}