http://www.oreillynet.com/onlamp/blog/2008/05/dynamic_languages_vs_editors.html
The first step for Ruby would fix a bug in both assert{ 2.0 } and Wrong.
(Unless I'm wrong, and Wrong gets this one right.)
Consider this assertion:
assert{ major_side_effect() }
If the assert passes, we only get a major side effect once.
But if the assert fails, we get the side effect twice.
The early fix is to enforce a rigorous demarcation between methods
with side-effects and methods with useful return values.
However, the point of developer tests is to enforce rigorous code, not
to RELY ON rigorous code.
And if one side effect changes the return value of the next call to
major_side_effect(), then the assertion will not reflect the value
that made it fail!
(That is why the top level value in assert{ 2.0 } diagnostic is the
actual block return value, regardless what the re-evaluated
expressions all say!)
The real fix is to add a mode to Ruby that journals each method call,
and stashes every stack frame's objects, with their types and current
states, into a big data structure.
assert{ 2.0 } and Wrong would then diagnose a fault, not by re-parsing
everything and re-evaluating everything, but by trivially reformatting
that stash.
And once we have this journaling, we can go farther, into the type
library that I propose in that paper.
So the question is: How to get that journaling from Ruby? (I suspect,
for example, that Python already has it, because in a Django web page
crash dump, you can expand each stack and see its local variable and
values.)
Ruby's kernel provides this:
set_trace_func lambda{|concept, file, line, symbol, binding, klass|
events << [file, line, symbol, concept, binding, klass, methods]
}
...but A> it provides no column, only a line (this is a problem with
Ruby's parser), and B> it stops short of providing the actual values.
Then, of course, we'd need to provide some way to pickle those
values's states, so when subsequent expressions in the call tree
change the states, the diagnostic reflections would not accidentally
follow an alias to the new values.
So does anyone have any idea how to get started?
--
Phlip
http://flea.sourceforge.net/resume.html <-- job seeking, BTW!
Note that the side effect doesn't have to be major or global. E.g.
assert { x.reverse! == 'abc' } will give a confusing message since x
will reverse back and forth several times in the course of building
the message. Moral: avoid side effects inside asserts (a good idea in
any framework, including DBC, the original assert).
Love your article. I too am amazed at how many editors don't get TDD.
I think it's because people who write editors tend to be those who
don't do TDD.
My biggest little peeve these days is that I can't tell the editor
what type a string is. I embed SQL, YAML, HTML, CSS, etc in my Ruby
strings and I want all the hilighting and completion i'd get in a
or .html or .css file.
Sent from my iPhone on a beach in Puerto Rico :-)
TextMate does this when you use the appropriately-named multiline string form:
(<<-HTML)
<html>
<body>
<i>hello world</i>
</body>
</html>
HTML