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 .