how to journal intermediate values in Ruby?

2 views
Skip to first unread message

Phlip

unread,
Oct 5, 2010, 10:56:48 PM10/5/10
to wron...@googlegroups.com
For my next magical trick, I want to do this:

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!

Alex Chaffee

unread,
Oct 6, 2010, 9:36:17 AM10/6/10
to wron...@googlegroups.com
Wrong gets it wrong, but only kinda. Since it would be stupid to say
"expected x but false" (since of course it's false, that's what
failing an assert means), we have to drill down into the
subexpressions and eval them. If eval has a side effect then oh well,
not sure what we can do (short of rewriting the interpreter in
beautifully evil ways like you suggest).

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 :-)

Steve Conover

unread,
Oct 6, 2010, 3:23:28 PM10/6/10
to wron...@googlegroups.com
> 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.

TextMate does this when you use the appropriately-named multiline string form:

(<<-HTML)
<html>
<body>
<i>hello world</i>
</body>
</html>
HTML

Screen shot 2010-10-06 at 12.21.52 PM.png

John Firebaugh

unread,
Oct 6, 2010, 4:37:45 PM10/6/10
to wron...@googlegroups.com
That is an awesome feature. Just requested it for RubyMine: http://youtrack.jetbrains.net/issue/RUBY-6890
Reply all
Reply to author
Forward
0 new messages