Inheriting Properties (or something similar) in IDLDOC [message #80787] |
Mon, 09 July 2012 17:05  |
Matt Francis
Messages: 94 Registered: May 2010
|
Member |
|
|
I've just started a project of re-commenting a large IDL code into
IDLDOC format and moving some external text file documentation into
those comments.
One issue I have is that the code uses IDL custom object, and in
particular inheritance, extensively. I would like the documentation
for derived classes to inherit appropriate info from the parent class
documentation.
In particular, the functionality of a lot of the object functions,
such as threshold levels and other parameters and switches are
controlled by config files. A base class may have some behaviour
controlled by some 'tag' in a config file and a derived class may be
controlled by additional tags. I would like a way to summarise all of
the config file tags that control an object (i.e. are looked at by any
of the objects functions) and then have derived classes documentation
inherit the summary from the superclass.
Looking over the IDLDOC reference guide, I though perhaps
the :Properties: tag in the file comments might allow this. So I have
comments in the base class <obj_name>__define.pro file that look
something like this:
;+
; Abstract Base class for handling input data for mapping.
; Provides a common interface for different data sources.
;
; :Properties:
; data_type : property name
; The IDL data type to use for the data storage array pointed to
by self.data
; somthing_else :
; Some other property
;-
This produces a nice summary of 'properties' in the IDLDOC produced
docs. However, this does not show up the doc page for derived classes
(not that I was expected to, just hoping....).
Is there any way to achieve what I'm trying to do? For comparison the
way IDLDOC handles the actual class members is exactly the behaviour I
want, but for a 'user defined' set of properties of objects. Is this
possible?
|
|
|
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #81214 is a reply to message #80787] |
Wed, 29 August 2012 11:14   |
Michael Galloy
Messages: 1114 Registered: April 2006
|
Senior Member |
|
|
On 8/29/12 1:10 AM, Yngvar Larsen wrote:
> On Tuesday, 10 July 2012 05:34:20 UTC+2, Mike Galloy wrote:
>> On 7/9/12 6:05 PM, Bogdanovist wrote:
>>
>>> I've just started a project of re-commenting a large IDL code into
>>
>>> IDLDOC format and moving some external text file documentation into
>>
>>> those comments.
>>
>>>
>>
>>> One issue I have is that the code uses IDL custom object, and in
>>
>>> particular inheritance, extensively. I would like the documentation
>>
>>> for derived classes to inherit appropriate info from the parent class
>>
>>> documentation.
>>
>>>
>>
>>> In particular, the functionality of a lot of the object functions,
>>
>>> such as threshold levels and other parameters and switches are
>>
>>> controlled by config files. A base class may have some behaviour
>>
>>> controlled by some 'tag' in a config file and a derived class may be
>>
>>> controlled by additional tags. I would like a way to summarise all of
>>
>>> the config file tags that control an object (i.e. are looked at by any
>>
>>> of the objects functions) and then have derived classes documentation
>>
>>> inherit the summary from the superclass.
>>
>>>
>>
>>> Looking over the IDLDOC reference guide, I though perhaps
>>
>>> the :Properties: tag in the file comments might allow this. So I have
>>
>>> comments in the base class <obj_name>__define.pro file that look
>>
>>> something like this:
>>
>>>
>>
>>> ;+
>>
>>> ; Abstract Base class for handling input data for mapping.
>>
>>> ; Provides a common interface for different data sources.
>>
>>> ;
>>
>>> ; :Properties:
>>
>>> ; data_type : property name
>>
>>> ; The IDL data type to use for the data storage array pointed to
>>
>>> by self.data
>>
>>> ; somthing_else :
>>
>>> ; Some other property
>>
>>> ;-
>>
>>>
>>
>>> This produces a nice summary of 'properties' in the IDLDOC produced
>>
>>> docs. However, this does not show up the doc page for derived classes
>>
>>> (not that I was expected to, just hoping....).
>>
>>>
>>
>>> Is there any way to achieve what I'm trying to do? For comparison the
>>
>>> way IDLDOC handles the actual class members is exactly the behaviour I
>>
>>> want, but for a 'user defined' set of properties of objects. Is this
>>
>>> possible?
>>
>>>
>>
>>
>>
>> Ah, no, not right now. That is an interesting feature though, that would
>>
>> be quite useful. I will make a feature ticket for that.
>>
>>
>>
>> One workaround for it right now would be to create a
>>
>> my_class_properties.idldoc page that lists all the properties for
>>
>> my_class and then (manually) link to that page from all the derived classes.
>>
>>
>>
>> Mike
>
> [Sorry for the late posting. Slowly catching up on the back log from this summer.]
>
> For what it's worth: I would also like this feature. In our software, we almost in every class use inheritance from a couple of base classes, and it would be nice if the methods from these would show up in the "Routine summary" in the derived classes.
>
The trunk now shows a listing of the inherited properties in the same
manner that the inherited fields are shown. Features/fixes are
collecting, so a release is probably going to happen soon.
But, you also want a listing of inherited routines?
Mike
--
Michael Galloy
www.michaelgalloy.com
Modern IDL: A Guide to IDL Programming (http://modernidl.idldev.com)
Research Mathematician
Tech-X Corporation
|
|
|
|
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #81378 is a reply to message #81263] |
Mon, 10 September 2012 02:14   |
tom.grydeland
Messages: 51 Registered: September 2012
|
Member |
|
|
On Monday, September 3, 2012 5:22:10 AM UTC+2, Mike Galloy wrote:
> I have fields and properties attached to classes so adding parent
> fields/properties is no problem. But I have to think about methods a bit
> more. It's just a bit more complicated because currently routines are
> attached to a File object, not directly to the Class object. What is
> displayed if there is only a single method in a file? What if there are
> multiple classes in a single file?
I think this points to a direction where the file is less important, and Classes and Routines matter more. (I suppose this echoes what Bogdanovist has said already).
You are already compiling the files and using introspection, right?
Can introspection tell you directly which methods belong to a class? If not, can you use the introspection equivalent of HELP, /ROUTINES to search for everything pertaining to a given CLASS (and its inheritance tree)? Can you use the equivalent of HELP, /SOURCE to list the file where a method is defined as part of the method description?
> Michael Galloy
--T (tom grydeland @ norut)
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #82950 is a reply to message #81214] |
Wed, 30 January 2013 04:04   |
tom.grydeland
Messages: 51 Registered: September 2012
|
Member |
|
|
On Wednesday, August 29, 2012 8:14:48 PM UTC+2, Mike Galloy wrote:
> But, you also want a listing of inherited routines?
This was exactly what we thought we would like for IDLDoc.
Given that the nicest possible way of asking for a new feature is to implement it, I present a pair of functions called SUPERCLASSES and METHOD_NAMES, and somehow I attach to them a hope for the requested feature to materialize in a future version of IDLdoc. METHOD_NAMES makes no attempt at distinguishing between function and procedure methods, but the extension to handle that should be straightforward.
> Michael Galloy
--Tom Grydeland
; docformat = 'rst'
;+
; :Copyright:
; (c) 2013, Northern Research Institute Tromsø AS (Norut),
; All rights reserved.
; This code can be redistributed in source and binary form
; under the same terms as the rest of the IDLdoc system.
;
; :Requires:
; IDL 8.0
;
; :Author: Tom Grydeland <tom.grydeland@norut.no>
;-
;+
; List all superclasses of an object or class name, in method search order
; (depth-first, left-to-right)
;
; Will attempt to compile class definitions in order to find their
; superclasses.
;
; :Params:
; obj : required, in
; an object, or the name of a class (a string)
;
; :Returns:
; A string array (may be empty)
;
; :Example:
; List all superclasses of 'gsar_reader'::
; IDL> print, transpose(superclasses('gsar_reader'))
;-
function superclasses, obj
compile_opt idl2, logical_predicate
case size(obj, /type) of
7 : classname=obj ;string
11 : classname=obj_class(obj)
else: message, 'Not an object' + string(obj)
endcase
catch, error_status
if error_status ne 0 then begin
message, 'unable to resolve ' + classname, /info
return, []
endif
resolve_routine, classname + '__define', /no_recompile
super = obj_class(classname, count=nsuper, /super)
if nsuper eq 0 then return, []
supersuper = []
for ii=0, nsuper-1 do begin
supersuper = [supersuper, super[ii], superclasses(super[ii])]
endfor
return, supersuper
end
; docformat = 'rst'
;+
; :Copyright:
; (c) 2013, Northern Research Institute Tromsø AS (Norut),
; All rights reserved.
; This code can be redistributed in source and binary form
; under the same terms as the rest of the IDLdoc system.
;
; :Requires:
; IDL 8.0
;
; :Author: Tom Grydeland <tom.grydeland@norut.no>
;-
;+
; List all methods of an object or class name, including inherited methods
;
; :Params:
; obj: required, in
; an object, or the name of a class (a string)
; whence: optional, out
; A hash that maps method name to superclass name
;
; :Returns:
; a string array of method names
;-
function method_names, obj, whence
compile_opt idl2, logical_predicate
case size(obj, /type) of
7 : classname=obj ;string
11 : classname=obj_class(obj)
else: message, 'Not an object' + string(obj)
endcase
routines = [routine_names(/proc), routine_names(/func)]
whence = hash()
;; find inherited methods and own methods
foreach class, [reverse(superclasses(classname)), classname] do begin
resolve_routine, class + '__define', /compile_full, /no_recompile
;; ii = where(strcmp(routines, super + '::', strlen(super)+2))
foreach method, routines[where(strcmp(routines, class + '::', strlen(class)+2, /fold_case))] do begin
parts = strsplit(method, '::', /extract)
if n_elements(parts) eq 2 then begin
whence[parts[1]] = parts[0] ; = class
endif
endforeach
endforeach
return, (whence.keys()).toArray()
end
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #83090 is a reply to message #82950] |
Sun, 03 February 2013 14:30   |
Michael Galloy
Messages: 1114 Registered: April 2006
|
Senior Member |
|
|
On 1/30/13 5:04 am, Tom Grydeland wrote:
> On Wednesday, August 29, 2012 8:14:48 PM UTC+2, Mike Galloy wrote:
>
>> But, you also want a listing of inherited routines?
>
> This was exactly what we thought we would like for IDLDoc.
>
> Given that the nicest possible way of asking for a new feature is to
> implement it, I present a pair of functions called SUPERCLASSES and
> METHOD_NAMES, and somehow I attach to them a hope for the requested
> feature to materialize in a future version of IDLdoc. METHOD_NAMES
> makes no attempt at distinguishing between function and procedure
> methods, but the extension to handle that should be straightforward.
OK, showing inherited methods is in the current master branch of IDLdoc.
See the output at:
http://docs.idldev.com/mglib/
In particular, see a subclass:
http://docs.idldev.com/mglib/collection/mgcoarraylist__defin e.html
This will be in the next release of IDLdoc. Let me know if you see any
problems.
Mike
--
Michael Galloy
www.michaelgalloy.com
Modern IDL: A Guide to IDL Programming (http://modernidl.idldev.com)
Research Mathematician
Tech-X Corporation
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #83116 is a reply to message #80787] |
Wed, 06 February 2013 11:10   |
Michael Galloy
Messages: 1114 Registered: April 2006
|
Senior Member |
|
|
On 2/6/13 7:42 AM, Tom Grydeland wrote:
> Basically, this looks good. I have a couple of issues:
>
> 1) Shadowed (or overridden) methods are listed. I would much prefer
> they weren't. Showing only the method that will be called makes
> browsing documentation much easier. In the currently produced
> documentation, you have to look through the complete method list to
> see which one will be called. (And are superclasses listed in
> inheritance order or not?) Granted, there are tasks where knowing
> about the shadowed methods of superclasses is useful, but I would
> prefer a different approach. For instance, the documentation for
> each method could have a small box (beneath the signature, before
> documentation) stating "Overrides definition from superclass
> idl_object", with link to the documentation for the superclass method
> (when applicable).
>
> 2) In the top-level listing (frames view), I followed "subclasses"
> links from idl_object__define to mg_graph_democlass__define. From
> this window, links to inherited methods did not work.
> (HREF=" http://docs.idldev.com/mglib/vis/objects/idl_object__define. html#idl_object::init#idl_object::init")
Ok, I have a fix for 2), its in the git repo now and the online docs
will be updated shortly.
1) will take a bit more thought.
Mike
--
Michael Galloy
www.michaelgalloy.com
Modern IDL: A Guide to IDL Programming (http://modernidl.idldev.com)
Research Mathematician
Tech-X Corporation
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #83133 is a reply to message #83090] |
Wed, 06 February 2013 06:42   |
tom.grydeland
Messages: 51 Registered: September 2012
|
Member |
|
|
On Sunday, February 3, 2013 10:30:00 PM UTC, Mike Galloy wrote:
> OK, showing inherited methods is in the current master branch of IDLdoc.
> See the output at:
> http://docs.idldev.com/mglib/
> In particular, see a subclass:
> http://docs.idldev.com/mglib/collection/mgcoarraylist__defin e.html
> This will be in the next release of IDLdoc. Let me know if you see any
> problems.
Basically, this looks good. I have a couple of issues:
1) Shadowed (or overridden) methods are listed. I would much prefer they weren't. Showing only the method that will be called makes browsing documentation much easier. In the currently produced documentation, you have to look through the complete method list to see which one will be called. (And are superclasses listed in inheritance order or not?) Granted, there are tasks where knowing about the shadowed methods of superclasses is useful, but I would prefer a different approach. For instance, the documentation for each method could have a small box (beneath the signature, before documentation) stating "Overrides definition from superclass idl_object", with link to the documentation for the superclass method (when applicable).
2) In the top-level listing (frames view), I followed "subclasses" links from idl_object__define to mg_graph_democlass__define. From this window, links to inherited methods did not work. (HREF=" http://docs.idldev.com/mglib/vis/objects/idl_object__define. html#idl_object::init#idl_object::init")
> Mike
Thanks,
--T
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #83152 is a reply to message #80787] |
Mon, 11 February 2013 01:48  |
tom.grydeland
Messages: 51 Registered: September 2012
|
Member |
|
|
On Monday, February 11, 2013 9:43:40 AM UTC, Tom Grydeland wrote:
> Here is a method for DOCTREECLASS that lists a class's inherited methods,
actually, _here_ it is (below).
My thought was that the getVariable method could grow a couple of new variables, such as 'n_inherited_methods' and 'inherited_methods':
'inherited_methods': begin
methods = self->getInheritedMethods()
return, methods
end
and the template 'profile.tt' etc could be modified to use these variables instead:
[% IF has_class %][% FOREACH class IN classes %][% SCOPE class %]
<h2>Inherited methods</h2>
[% IF n_inherited_methods gt 0L %]
[% FOREACH r IN inherited_methods %][% SCOPE r %]
etc etc etc
[% END %][% END %][% END %]
[% END %][% END %][% END %]
but I have not been able to figure out how to make this work. I may be missing something obvious.
function doctreeclass::getInheritedMethods
compile_opt strictarr, hidden
; First, find all methods of all ancestors in inheritance order
inhm = obj_new('MGcoHashtable', key_type=7, value_type=11)
n_anc = self.ancestors->count()
for a = 0L, n_anc - 1L do begin
anc = self.ancestors->get(position=n_anc-a-1L)
methods = anc->getVariable('visible_methods')
for m = 0L, n_elements(methods) - 1L do begin
m_name = methods[m]->getVariable('name')
parts = strsplit(m_name, '::', /extract)
if n_elements(parts) ne 2 then continue
inhm->put, parts[1], methods[m]
endfor
endfor
; Next, if there is a direct method of the same name, delete the inherited
; method
n_meth = self.methods->count()
if n_meth ne 0 then begin
keys = self.methods->keys()
for m = 0L, n_meth - 1L do begin
parts = strsplit(keys[m], '::', /extract)
inhm->remove, parts[1]
endfor
endif
methods = inhm->values()
; cleanup
return, methods
end
|
|
|
Re: Inheriting Properties (or something similar) in IDLDOC [message #83153 is a reply to message #83116] |
Mon, 11 February 2013 01:43  |
tom.grydeland
Messages: 51 Registered: September 2012
|
Member |
|
|
> On 2/6/13 7:42 AM, Tom Grydeland wrote:
>> 1) Shadowed (or overridden) methods are listed. I would much prefer
>> they weren't.
On Wednesday, February 6, 2013 7:10:49 PM UTC, Mike Galloy wrote:
> 1) will take a bit more thought.
Okay, I'll bite (again).
Here is a method for DOCTREECLASS that lists a class's inherited methods, obeying inheritance order, and with methods shadowed by the class's own methods removed.
This method also exposes a bug in MGcoHashTable::values(). Whenever values had been removed so that the list for a particular bucket was empty, the expression "list->get(/all)" would return -1. This value is overwritten on the next iteration, but in my usage values are objects and -1 is not a valid value.
The fix is to replace the test on line 407 of mgcohashtable__define.pro with
if (obj_valid(list) && list->count() gt 0) then begin
> Mike
--T
|
|
|