RCR? change Proc#inspect to show start..end lines

J

Joel VanderWerf

Proc#inspect typically returns a string like:

#<Proc:[email protected]:3>

where the "3" is the first line of the code block in file "file.rb".

It would be easier to extract the entire code block without doing
parsing if Proc#inspect returned a _range_ of lines:

#<Proc:[email protected]:3..5>

It would also be nice to have reader methods to get this information
from the proc:

Proc#file
Proc#line_start
Proc#line_finish

Opinions? Is there something simple I'm missing?

I thought that eval-ing __LINE__ against the proc's binding might give
the last line of the proc's definition, but actually the results are
surprisingly inconsistent:

$ cat t1.rb
pr = proc {
1+1
puts
}

p eval("__LINE__", pr)

$ ruby t1.rb
2

$ cat t2.rb
pr = proc {
x=1+1
puts
}

p eval("__LINE__", pr)

$ ruby t2.rb
4
 
F

Florian Gross

Joel said:
It would be easier to extract the entire code block without doing
parsing if Proc#inspect returned a _range_ of lines:

Heh, are you wanting to do the same that I want to? :)

(See http://noegnud.sourceforge.net/flgr/proc_source.rb -- I'm doing
lots of manual parsing there however.)
It would also be nice to have reader methods to get this information
from the proc:

Proc#file
Proc#line_start
Proc#line_finish

If we're adding this we might as well think about adding a character
index for both the start and the finish which would allow us to find the
correct source code even if there are multiple Procs on the same line.

(Plus if we had that, we wouldn't need to do any manual parsing at all.)

Oh, and it would be great if there was a way to overload eval() without
breaking anything. Currently if one does that this won't work any more:
a = 5; eval "a"

But we might not get a way to do that before the eval:pre-style hooks
anyway.

Regards,
Florian Gross
 
J

Joel VanderWerf

Florian said:
Heh, are you wanting to do the same that I want to? :)

(See http://noegnud.sourceforge.net/flgr/proc_source.rb -- I'm doing
lots of manual parsing there however.)

That's much more sophisticated than what I need. I've got a little
debugger for a domain-specific language embedded in ruby, and I want to
show what a proc is about to do. So all I need is first and last line
numbers.

Great hack, though :)
 
N

nobu.nokada

Hi,

At Tue, 25 May 2004 05:39:16 +0900,
Joel VanderWerf wrote in [ruby-talk:101253]:
It would be easier to extract the entire code block without doing
parsing if Proc#inspect returned a _range_ of lines:

#<Proc:[email protected]:3..5>

Unfortunately, there's no more room for it.
I thought that eval-ing __LINE__ against the proc's binding might give
the last line of the proc's definition, but actually the results are
surprisingly inconsistent:

I think this has no bad side effects.


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.665
diff -u -2 -p -r1.665 eval.c
--- eval.c 25 May 2004 02:54:21 -0000 1.665
+++ eval.c 25 May 2004 08:49:56 -0000
@@ -2932,4 +2932,5 @@ rb_eval(self, n)
PUSH_ITER(ITER_PRE);
if (nd_type(node) == NODE_ITER) {
+ ruby_frame->node = node;
result = rb_eval(self, node->nd_iter);
}
@@ -6043,8 +6044,8 @@ eval(self, src, scope, file, line)
old_wrapper = ruby_wrapper;
ruby_wrapper = data->wrapper;
- if ((file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) && data->body) {
- file = data->body->nd_file;
+ if (file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) {
+ file = data->frame.node->nd_file;
if (!file) file = "__builtin__";
- line = nd_line(data->body);
+ line = nd_line(data->frame.node);
}
 
J

Joel VanderWerf

Hi,

At Tue, 25 May 2004 05:39:16 +0900,
Joel VanderWerf wrote in [ruby-talk:101253]:
It would be easier to extract the entire code block without doing
parsing if Proc#inspect returned a _range_ of lines:

#<Proc:[email protected]:3..5>


Unfortunately, there's no more room for it.

Oh, well. :/
I think this has no bad side effects.


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.665
diff -u -2 -p -r1.665 eval.c
--- eval.c 25 May 2004 02:54:21 -0000 1.665
+++ eval.c 25 May 2004 08:49:56 -0000
@@ -2932,4 +2932,5 @@ rb_eval(self, n)
PUSH_ITER(ITER_PRE);
if (nd_type(node) == NODE_ITER) {
+ ruby_frame->node = node;
result = rb_eval(self, node->nd_iter);
}
@@ -6043,8 +6044,8 @@ eval(self, src, scope, file, line)
old_wrapper = ruby_wrapper;
ruby_wrapper = data->wrapper;
- if ((file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) && data->body) {
- file = data->body->nd_file;
+ if (file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) {
+ file = data->frame.node->nd_file;
if (!file) file = "__builtin__";
- line = nd_line(data->body);
+ line = nd_line(data->frame.node);
}


The effect of this is to make __LINE__ more consistent, but it's still
the first line of the proc, just as is reported in Proc#inspect:

$ cat t1.rb
pr = proc {
1+1
puts
}

p eval("__LINE__", pr)
p pr
[~/ruby/prj/redshift/examples] ruby t1.rb
1
#<Proc:[email protected]:1>

I'm not really sure what __LINE__ should eval to, but this behavior
doesn't help me find the start and end lines in the source file.

I guess I can do some parsing, following Florian's example.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: RCR? change Proc#inspect to show start..end lines"

|> I thought that eval-ing __LINE__ against the proc's binding might give
|> the last line of the proc's definition, but actually the results are
|> surprisingly inconsistent:
|
|I think this has no bad side effects.

Commit the patch, please.

matz.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,796
Messages
2,569,645
Members
45,371
Latest member
TroyHursey

Latest Threads

Top