Situation:
I create a class "C" with instproc "foo". An object is created from C called "ob".
Problem:
The commands "ob info procs", "ob info args" and "ob info body" do not work as I would expect them to. In particular, there doesn't seem to be a way of finding out the body and arguments for the instproc "foo" from the object. I could do this by asking the class, but I specifically would like a uniform way to do this, without caring whether the methods are inherited or not. Is this intended? Why?
% package require XOTcl 0.85
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Saturday 11 August 2001 00:00, Kristoffer Lawson wrote:
Situation:
I create a class "C" with instproc "foo". An object is created from C called "ob".
Problem:
The commands "ob info procs", "ob info args" and "ob info body" do not work as I would expect them to. In particular, there doesn't seem to be a way of finding out the body and arguments for the instproc "foo" from the object. I could do this by asking the class, but I specifically would like a uniform way to do this, without caring whether the methods are inherited or not. Is this intended? Why?
You can do this pretty easy with:
% [ob info class] info instprocs
... and similar.
AFAIK, the "ob info procs|args|body" is ment to be used with per-object resources (procs), like for example:
% ob proc bar args {puts $args} % ob info procs bar % ob info body bar puts $args % ob info args bar args
If you change the current behaviour, how would you cover this issue then ?
Regards, Zoran
On Sat, 11 Aug 2001, Zoran Vasiljevic wrote:
You can do this pretty easy with:
% [ob info class] info instprocs
... and similar.
That is what I do, but required me to know that a proc is inherited from somewhere! I have both types, procs and instprocs (which are both callable from the object) and I would like to be able to ask information about them without knowing where they're from.
AFAIK, the "ob info procs|args|body" is ment to be used with per-object resources (procs), like for example:
Yes, that what it appears to do, but as such it's limited. I would like a uniform way of asking information about inherited procs and per-instance procs. In fact I might even say that to separate those on this level is confusing the object model.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Saturday 11 August 2001 23:07, you wrote:
On Sat, 11 Aug 2001, Zoran Vasiljevic wrote:
You can do this pretty easy with:
% [ob info class] info instprocs
... and similar.
That is what I do, but required me to know that a proc is inherited from somewhere! I have both types, procs and instprocs (which are both callable from the object) and I would like to be able to ask information about them without knowing where they're from.
AFAIK, the "ob info procs|args|body" is ment to be used with per-object resources (procs), like for example:
Yes, that what it appears to do, but as such it's limited. I would like a uniform way of asking information about inherited procs and per-instance procs. In fact I might even say that to separate those on this level is confusing the object model.
I know this problem. The possible solution is to use procsearch function if you know the name of method
set proc [$ob procsearch proc]
and ask the standard tcl info if {$proc!=""} { info args $proc }
To get all posible methods for some object in not so easy. I use something like that in XOTclIDE
Class instproc getAllInstMethods {} { set methods [[self] info instprocs] foreach class [[self] info heritage] { set methods [concat $methods [$class info instprocs]] } return [lsort -unique $methods] }
You also must look for all mixins classes and procs methods $object info mixin
Object instproc allAvailableMethods {} { ::set method {} foreach class [concat [[self] info class] [[self] info mixin]] { ::set method [concat $method [$class getAllInstMethods]] } ::set method [concat $method [[self] info procs]] return [lsort -unique $method] }
There are also class mixins (not implemented above).
happy hacking Artur Trzewik
On Sun, 12 Aug 2001, Artur Trzewik wrote:
I know this problem. The possible solution is to use procsearch function if you know the name of method
Yes, you're solution should work (actually I thought you might have something because of XOTclIDE's need for that), but it's still a bit of tweaking. XOTcl should still probably provide a uniform way to ask information like that.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Saturday 11 August 2001 23:07, Kristoffer Lawson wrote:
AFAIK, the "ob info procs|args|body" is ment to be used with per-object resources (procs), like for example:
Yes, that what it appears to do, but as such it's limited. I would like a uniform way of asking information about inherited procs and per-instance procs. In fact I might even say that to separate those on this level is confusing the object model.
I do understand now what you mean. You'd like a general introspection interface, w/o needing to know wether you're dealing with a per-instance proc or an instproc. Seems logical.
So you'd say:
ob info body foo ob info body bar
or
ob info args foo ob info args bar
without extra knowledge about what are "foo" and "bar" actually. The "foo" may be an instproc whereas the "bar" may be a per-instance proc or vice versa. Correct?
I think such behaviour can be implemented with some XOTcl wrappers using existing introspection capabilities of the system. I might be wrong of course. Maybe Uwe and/or Gustaf can say something about it?
I would, for example, override the "info" method with some custom code which tries the per-instance proc first and if it does not find any, goes to the instproc. This should't be difficult to implement.
Cheers Zoran
On Sun, 12 Aug 2001, Zoran Vasiljevic wrote:
without extra knowledge about what are "foo" and "bar" actually. The "foo" may be an instproc whereas the "bar" may be a per-instance proc or vice versa. Correct?
Yes, exactly. I also believe that kind of introspection is quite natural for an object syste. While inheritance is naturally useful, I still like to think of objects as independent entities. Thus to do the above feels useful.
I would, for example, override the "info" method with some custom code which tries the per-instance proc first and if it does not find any, goes to the instproc. This should't be difficult to implement.
It is possible to do (I think), but I'm wondering if this is an oversight in the info functionality provided by XOTcl? It is a bit messy to first test for if a procedure exists in the object, and then search the class, and then any possible mixin class. The same must be done again for getting a list of available methods. And then up to the superclasses.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Saturday 11 August 2001 00:00, Kristoffer Lawson wrote:
Situation:
I create a class "C" with instproc "foo". An object is created from C called "ob".
Problem:
The commands "ob info procs", "ob info args" and "ob info body" do not work as I would expect them to. In particular, there doesn't seem to be a way of finding out the body and arguments for the instproc "foo" from the object. I could do this by asking the class, but I specifically would like a uniform way to do this, without caring whether the methods are inherited or not. Is this intended? Why?
Much of the answers have been said already.
The right way to query instprocs is via "info instargs" and "info instbody" rather than "info args" and "info body" or the tcl counterparts...
===================================================
Class C
::C
C instproc foo {a b c} {puts foo} C c1
::c1
C info instprocs
foo
C info instargs foo
a b c
C info instbody foo
puts foo ====================================================
on our todo-list for 0.85 we have an issue for returning names of procs/instprocs/mixins/filters etc. in a consistent way, that also effects procsearch. This becomes neccessary for [self next], which lets a user query, what will be called next (filter, mixin, proc, instproc).
in the best of all possible worlds, we treat whatever comes back fron the query an an object which has an orthogonal query interface for instrospection. speedwise an object is rather heavyweight, so we think about list notations as well. OTH, we the xotcl-objects are not necessarily tcl-based, these can be c-based as well (we have a mostly working SWIG bindig for xotcl), therefore the speed penalty wont be large....
greeting -gustaf PS: hopefully, i can put 0.85.3 this evening on the server.
On Mon, 13 Aug 2001, Gustaf Neumann wrote:
The right way to query instprocs is via "info instargs" and "info instbody" rather than "info args" and "info body" or the tcl counterparts...
Well, as mentioned, this does not really work in my case. I do not know beforehand whether a proc is an instproc or a per-object proc. I am using meta-programming and using methods as templates for other dynamically built methods. When the API gets the name of the method, it asks for the body and arguments, so it can create another method with that information. When looking up that information it now assumes that the given method name is an instproc and asks the class -- but this is not a general solution.
As pointed out by Artur, there are ways to do this, but they're pretty complex, so I am looking for a straightforward way of asking information about a method, without caring about whether it's inherited or not.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Monday 13 August 2001 15:52, you wrote:
On Mon, 13 Aug 2001, Gustaf Neumann wrote:
The right way to query instprocs is via "info instargs" and "info instbody" rather than "info args" and "info body" or the tcl counterparts...
Well, as mentioned, this does not really work in my case. I do not know beforehand whether a proc is an instproc or a per-object proc. I am using meta-programming and using methods as templates for other dynamically built methods. When the API gets the name of the method, it asks for the body and arguments, so it can create another method with that information. When looking up that information it now assumes that the given method name is an instproc and asks the class -- but this is not a general solution.
As pointed out by Artur, there are ways to do this, but they're pretty complex, so I am looking for a straightforward way of asking information about a method, without caring about whether it's inherited or not.
sure. the point is, that we need both: an explicit interface for getting the details right and for distinguising as far as neccessary, and a high level interface, that hides part of this details for a user who does not care about these. for the latter case, an "info procs" or "info instprocs" is not the right way, since the names are not necessarily disjunct. a new thing called "info methods" that returns a list of method-objects (see last mail) could help here returning all the callable methods (which are procs, instprocs, mixins, filters).
what is it, that would fit your needs best? what are you doing exactly?
-gustaf
On Mon, 13 Aug 2001, Gustaf Neumann wrote:
sure. the point is, that we need both: an explicit interface for getting the details right and for distinguising as far as neccessary, and a high level interface, that hides part of this details for a user who does not care about these. for the latter case, an "info procs" or "info instprocs" is not the right way, since the names are not necessarily disjunct. a new thing called "info methods" that returns a list of method-objects (see last mail) could help here returning all the callable methods (which are procs, instprocs, mixins, filters).
what is it, that would fit your needs best? what are you doing exactly?
Well for me even more important are the "info args" and "info body" parts. As mentioned, I'm doing some meta-programming at the moment. I have a method which generates more methods based on a template method (an example of this can be found at: http://mini.net/cgi-bin/wikit/401.html). Right now the method-generators assumes that the template is inherited from a class (so checks "args" and "body" from there), but really it should not care whether a method is inherited or not. It should just be given the name of the method, and it can ask the information regardless of inheritance.
I'm not quite sure what the best way to do this would be, while still keeping the old logic. Maybe something like your "method" proposal, or alternatively an extra option to the current "info body" etc. commands.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Monday 13 August 2001 18:15, Kristoffer Lawson wrote:
On Mon, 13 Aug 2001, Gustaf Neumann wrote:
what is it, that would fit your needs best? what are you doing exactly?
Well for me even more important are the "info args" and "info body" parts. As mentioned, I'm doing some meta-programming at the moment.
meta-programming is a wonderful thing. actually, several years ago, i wrote a book about it (in the context of Prolog, see my homepage) covering meta-interpreters and partial evaluation in particular....
I have a method which generates more methods based on a template method (an example of this can be found at: http://mini.net/cgi-bin/wikit/401.html). Right now the method-generators assumes that the template is inherited from a class (so checks "args" and "body" from there), but really it should not care whether a method is inherited or not. It should just be given the name of the method, and it can ask the information regardless of inheritance.
hmm. you mentioned here twice "args" and "body"; you should not use these for inherited methods, use instead "instargs" and "instbody".
i am still confused. Are you trying to use the instprocs as templates for procs? if i paraphrase the example from the wiki, this would be
Class C C instproc fooTemplate <argument> <body>
C c1 useTemplate c1 fooTemplate foo -msg1 Hi -msg2 bye
where the object c1 has afterwards a proc foo, and fooTemplate could be a proc or an instproc.
i do not think, that this is a good solution, but this is an example where i would like to ignore the differences between procs and instprocs. is this similar to what you are working on?
-gustaf
On Mon, 13 Aug 2001, Gustaf Neumann wrote:
hmm. you mentioned here twice "args" and "body"; you should not use these for inherited methods, use instead "instargs" and "instbody".
That's the point, the method-generator should know be concerned with whether the template methods are inherited or not!
i am still confused. Are you trying to use the instprocs as templates for procs? if i paraphrase the example from the wiki, this would be
Class C C instproc fooTemplate <argument> <body>
C c1 useTemplate c1 fooTemplate foo -msg1 Hi -msg2 bye
where the object c1 has afterwards a proc foo, and fooTemplate could be a proc or an instproc.
i do not think, that this is a good solution, but this is an example where i would like to ignore the differences between procs and instprocs. is this similar to what you are working on?
This is pretty much exactly what I am doing, albeit with metaclasses and classes.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
sure. the point is, that we need both: an explicit interface for getting the details right and for distinguising as far as neccessary, and a high level interface, that hides part of this details for a user who does not care about these. for the latter case, an "info procs" or "info instprocs" is not the right way, since the names are not necessarily disjunct. a new thing called "info methods" that returns a list of method-objects (see last mail) could help here returning all the callable methods (which are procs, instprocs, mixins, filters).
what is it, that would fit your needs best? what are you doing exactly?
Yes. I thing such new interface is needed
$object info methods
Is one to get all methods that object can understand.
Another one is to get additional meta information I use this method to get all instprocs and the place, where they are defined for my purposes.
Class instproc getAllFullInstMethods {} { set fmethods {} foreach m [[self] info instprocs] { lappend fmethods [list $m [self]] set marr($m) 1 } foreach class [[self] info heritage] { foreach m [$class info instprocs] { if {![::info exist marr($m)]} { lappend fmethods [list $m $class] set marr($m) 1 } } } return $fmethods }
Such think sould be implemented internally (and not so unclean) and can be used also for procs and mixins (instance or class).
$object info fullMethods myMethod sould return list {methodName methodType definitionPlace}
for example
Class A A instproc foo1 A instproc foo2 Class B B instproc foo1
B b b proc foo3
b info fullMethods
{foo3 proc b} {foo1 instproc B} {foo2 instproc A}
b info methods
{foo1 foo2 foo3}
I think the method type can be rather not needed if man use [Object isclass A]
Very similar interface is known by Smalltalk Object>>responseTo: method (return true or false if object understand message)
Behavior>>allSelectors (get all methods)
Behavior>>findSelector: method (get the definition class of method)
Artur Trzewik
Such think sould be implemented internally (and not so unclean) and can be used also for procs and mixins (instance or class).
$object info fullMethods myMethod sould return list {methodName methodType definitionPlace}
for example
Class A A instproc foo1 A instproc foo2 Class B B instproc foo1
B b b proc foo3
b info fullMethods
{foo3 proc b} {foo1 instproc B} {foo2 instproc A}
this is more or less what we have currently scheduled for 0.86 used as result for [self next] and [.. procsearch ....]. actually, having another order, such it has the same order as in the definition.
{b foo3 proc} {B instproc foo1} {A instproc foo2}
however, it would be still nicer to have methods as objects.
{m1 m2 m3}
[m1 class] -> Proc [m2 class] -> Instproc [m3 name] -> foo2
this would allow more methods on procs/instprocs and this is extensible with more metadata (e.g. pre/post conditions, c-code vs. tcl-code -> getting rid of the distinction of instcommand vs. instprocs ....).
Another interesting idea is to use aggregations for methods.
Class C C proc f {} {...} C instproc m {} {...}
would lead to C::f C::m where C::f amd C::m being of class Proc or Instproc
one could even use
Class C Proc C::f {} {...} Instproc C::m {} {....}
In the most straightforward case, this would exclude having instproc and procs of the same name, which is not great (OTH, other OO languages do not allow these either)... the cool part is that it is very easy to find out, where the command is defined, and moving, renaming etc. could work with the standard move/rename etc. methods, and "info procs" is not much more than a specialized "info children"....the long list of things in "info info" can be reduce....
but there are as well many arguments against it. one thing is memory consumption. to even think about it, we should find a way of defining lightweight objects....
-gustaf
PS: no, i am not thinking about implementing it, i am just thinking loudly.
On Tue, 14 Aug 2001, Gustaf Neumann wrote:
however, it would be still nicer to have methods as objects.
It's a nice idea, but how do you solve the infinite recursion problem? If all methods are objects, then methods on method objects should also be objects and thus have methods etc.
Another related issue would be to make all messages objects so you could freely ask information on every received message.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Tuesday 14 August 2001 04:10, you wrote:
this is more or less what we have currently scheduled for 0.86 used as result for [self next] and [.. procsearch ....]. actually, having another order, such it has the same order as in the definition.
{b foo3 proc} {B instproc foo1} {A instproc foo2}
however, it would be still nicer to have methods as objects.
{m1 m2 m3}
[m1 class] -> Proc [m2 class] -> Instproc [m3 name] -> foo2
this would allow more methods on procs/instprocs and this is extensible with more metadata (e.g. pre/post conditions, c-code vs. tcl-code -> getting rid of the distinction of instcommand vs. instprocs ....).
Another interesting idea is to use aggregations for methods.
Class C C proc f {} {...} C instproc m {} {...}
would lead to C::f C::m where C::f amd C::m being of class Proc or Instproc
one could even use
Class C Proc C::f {} {...} Instproc C::m {} {....}
In the most straightforward case, this would exclude having instproc and procs of the same name, which is not great (OTH, other OO languages do not allow these either)... the cool part is that it is very easy to find out, where the command is defined, and moving, renaming etc. could work with the standard move/rename etc. methods, and "info procs" is not much more than a specialized "info children"....the long list of things in "info info" can be reduce....
but there are as well many arguments against it. one thing is memory consumption. to even think about it, we should find a way of defining lightweight objects....
I think it is a general problem of XOTcl. It is based on Tcl. Tcl is string oriented. We say everything is the list (string). Also internal interpreter interface (Tcl_Obj) is based on this principle. So internal object can be converted to string and we can build internal objects from string. XOTcl objects are based on so called handlers principle. Therefore XOTcl can not offer so complete (ger. durchgängig) language principle. everything is an object (see Smalltalk). That is not so tragic. I think the importest thing is to get good mix between list and object-oriented world.
The lightweigh objects are very important for such think as interface to other languages (C++). The possible solution (see my maligns to garbage collection) is to make XOTcl also internal really Tcl objects. This is hardly possible with actual Tcl interpreter. The second thing is that XOTcl will become another incompatible to early version language.
So I am very anxious on next development of XOTcl "(we have a mostly working SWIG bindig for xotcl)" that will be cool
Artur Trzewik