Friday, March 11, 2011

How to find the Magik source file for an exemplar definition

Many of you are likely aware of the object.method(method_name).source_file pattern that you can use to determine the file in which the method definition is contained. But did you know that you could also use the same pattern to find the file location for the actual object exemplar?

For example, in my Web Maps Connector image, I want to figure out where map_view.int!do_render() is actually defined. I can do the following to get that information.

MagikSF> map_view.method(:int!do_render|()|).source_file
$
"C:\ifactor\products\workspace\Virtual_Earth_Connector\trunk\source\patches_z_proposed\p1000001_1_if_vec_map_plugin.magik"

But what if I want to determine how that patch of map_view.int!do_render() has modified the original version of that method? Where can I find that original method definition? While it is not 100% guaranteed, Magik style conventions strongly suggest that object method definitions be kept in the same file as the object's exemplar definition. Great. So all we need to do is find the file in which the def_slotted_exemplar(:map_view) is called. Here is how you do that...

MagikSF> map_view.method(:exemplar).source_file
$
"C:/Smallworld41/product/modules/sw_swaf/map_plugin/source/map_view.magik"


The trick is to request the source file for the special method called :exemplar. Happy debugging!

2 comments:

Anonymous said...

or you can use map_view.exemplar_global.source_file

Chris said...

We use the proc below to find the location of all methods for an exemplar.

print_local_methods_and_path <<
_proc(an_exemplar,_optional including_private?)
## Lists all files and the methods which are defined on the class of
## AN_EXEMPLAR rather than inherited.

f_and_m << equality_hash_table.new()

_for m _over an_exemplar.define_method_target.local_methods(including_private?)
_loop
afile << m.source_file.default("unset")

_if f_and_m[afile] _is _unset
_then
f_and_m[afile] << rope.new()
_endif

f_and_m[afile].add(m)
_endloop

_for file, methods _over f_and_m.fast_keys_and_elements()
_loop
!output!.write(%- * file.size, newline_char)
!output!.write(file, newline_char)
_for m _over methods.fast_elements()
_loop
!output!.write(tab_char, m)
!output!.newline()
_endloop
_endloop
_endproc
$