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

Proc#inspect typically returns a string like:

#Proc:0x401c6d54@file.rb: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:0x401c6d54@file.rb: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

Joel VanderWerf wrote:

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? :slight_smile:

(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

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:0x401c6d54@file.rb: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);
    
    }


Nobu Nakada

Florian Gross wrote:

Joel VanderWerf wrote:

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? :slight_smile:

(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 :slight_smile:

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:0x401c6d54@file.rb:3..5

Unfortunately, there’s no more room for it.

Oh, well. :confused:

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);
    
    }

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:0x401c6e80@t1.rb: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.

···

nobu.nokada@softhome.net wrote:

Hi,

···

In message “Re: RCR? change Proc#inspect to show start…end lines” on 04/05/25, nobu.nokada@softhome.net nobu.nokada@softhome.net writes:

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.