
Submitted by eric_mahurin (Sun Sep 11 13:10:51 UTC 2005)
1. takes an expression. There are several options:
a. as a block. i.e. {i+1}
b. as an argument (caller evaluates). i.e. (i+1)
c. as a string argument. i.e. ('i+1')
d. as a string within a block. i.e. {'i+1'}
2. evaluates the expression in the caller context
3. if some debug/trace condition, prints out as much info as possible about the expression - file, line, expression string, expression result.
4. returns the expression result
x = 1 y = 2 + x/3
And you want to debug/trace x/3. Right now, you'd do something like this:
x = 1
y = 2 + (tmp=x/3)
puts("#{__LINE__}: #{tmp.inspect}") if $DEBUG
With this proposal (using 1.a. option above and a method name of "d"), you'd have this:
x = 1
y = 2 + d{x/3}
Regarding the various expression options above, here are the disadvantages (nothing is perfect):
a. block: can't get the expession string and a little slower than a direct argument. Hopefully some mechanism will be put in place in a future ruby to get this from a proc/lambda/block. The main info missing to get this now is a token or column number (we have file and line number now).
b. argument: can't get the expession string. Although possible with a token or column number (in Kernel#caller) like the expression in a block, it is harder and getting a string from a proc/lambda/block may have another solution in the future.
c. string argument: very slow, expression highlighted as a string in text editors, and hard to get the binding of the caller to evaluate the expression. Florian has a solution for getting the caller binding, but it uses continuations and would be significantly slower. Also, the eval will be slow relative to a block yield (even with simple expressions I find it to be 20-30X).
d. string in a block: slow, expression highlighted as a string in text editors. The binding can be easily retrieved since the string is passed in a block, but the slowness of eval still reveals itself.
I recommend the 1.a. solution hoping for a robust Proc/lambda/block to code string method in the future.
Here are some related RCR's:
https://rcrchive.net/rcr/show/174 (legacy)
https://rcrchive.net/rcr/show/255
This RCR combines features from both but uses a different method name rather than changing Kernel#p.
module Kernel
def d(debug=$DEBUG,&block)
if debug
result = yield
$stderr.printf("DEBUG: %s #=> %s\n",
caller[0],result.inspect)
result
else
yield
end
end
end

| Comments | Current voting | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
I like your overall idea, but how about 'trace' instead of 'd'. I'm not a fan of one-letter method names.
|
|


RCRchive copyright © David Alan Black, 2003-2005.
Powered by .