My recent hobby project (dnd - a console-based TODO list) is written in Ioke. I am surprised how easy is to learn Ioke and how fast it is possible to achieve great results in this language. The problem is that it's so powerful, it's easy to get out of chosen path and end up in bushes without even noticing.
This problem is especially important now, when I'm exploring the language - and most of the code I write changes too fast to be easily harnessed by tests. Without tests in the picture I must rely on simple println to actually see where I'm going.
Adding print statements throughout the code is boring and cumbersome and I'm a lazy person. Ioke has great support for aspects so why not use that?
The best way to see where the program is going is to inspect what cells are called and what do they return. Ioke provides pointcuts for those two events, you can create and add methods to them using before and after methods available on all objects.
When you want to log method call you write something similar to:
object before(matching: :anyFromSelf) << macro("called #{call receiver}:#{call message name}(#{call arguments})" println)
Similar, when you want to log method's return you use after
object after(matching: :anyFromSelf) << macro("returned #{aspectResult asText}" println)
This is all nice but a more useful thing is an Object that wraps everything nicely and provides simple call graph:
CallInspector = Origin mimic do(
nesting = 0
entering = lecrox(
"#{"| " * nesting}+called #{call receiver}:#{call message name}(#{call arguments})" println
nesting ++
)
leaving = lecrox(
nesting --
"#{"| " * nesting}\\returned #{aspectResult asText truncate}" println
)
instrument = method(+objects,
objects each(object,
object before(matching: :anyFromSelf) << entering
object after(matching: :anyFromSelf) << leaving
)
)
)
You can use it in your code with:
CallInspector instrument(YourObject, AndAnother)
The most recent version of CallInspector is available on gist.