Thanks @mig, feedback such as yours is exactly what I was hoping for.
    
    
    This looks like an interesting learning exercise, but in what situations is 
this useful?
    
    
    Run

My motivation for this is far from just being a learning exercise. 
Unfortunately I only included examples with `object` types in the `README.md` 
file, which gives a false impression that such types were my sole target.

The test examples in the `when isMainModule:` section of `destructor.nim` show 
a whole lot more.

Here is what motivated me to undertake this.

My main project is a UI library, with ~100 `ref object` (not `object`) types, 
with fields of one entity typically referring to several other entities. Any 
application using this library would generate extensive trees of such entities, 
that are dynamically created and destroyed as the application proceeds.

My current task in that project is to implement ``=destroy`` hooks for all of 
the above types, each of which includes optional printing of trace messages to 
help isolate problems such as memory leaks.

When I started doing so, I quickly realized that I was wasting a lot of time 
writing duplicate fragments of code:
    
    
    proc `=destroy`(<blah>) =
      when defined(traceDestructors):
        echo "Destructor for type <blah> with <tag field> = ", x.tagfield
      
      when defined(traceDestructors):
        echo "destroy field <field name> of type <blah>"
      `=destroy`(<field blah>
      
      <...blah blah for each field being destroyed>
      
      when defined(traceDestructors):
        echo "destroy base type <base type>"
      `=destroy`(<base type blah>
    
    
    Run

There has to be a better way. I need a helper to eliminate as much of such 
cruft as possible.

The requirements of this helper are as follows:

  * Generate `=destroy` hook implementations for both `ref object` and `object` 
types
  * Generate `=destroy` calls for all destroyable (or liftable?) field types - 
`object`, `ref object`, `string`, `seq`, `array`, closure, etc., as specified 
by the user.
  * Generate an ``=destroy`` call for the base type if needed.
  * Allow the user to mingle custom finalization code into the generated 
``=destroy`` code, in whatever manner the application requires.
    * For example, my main project uses `opengl` and `sdl2`. A follow-up task 
there is to clean up their associated resources when a UI element is destroyed
  * Allow optional generation of trace messages to assist in debugging



I chose a macro implementation because I am starting to understand how to write 
them. ("When you have a hammer, everything around you is a nail" :D).

Your idea of using a template looks interesting. Unfortunately I don't yet have 
a good understanding of what can be done with templates, so I don't know if 
that approach allows the flexibility I need to fulfill the above requirements. 

Reply via email to