Project

General

Profile

This project is closed and read-only.

Actions

Bug #3011

closed

caller for recursive function

Bug #3011: caller for recursive function

Added by marcandre (Marc-Andre Lafortune) over 16 years ago. Updated over 14 years ago.

Status:
Closed
Target version:
ruby -v:
ruby 1.8.8dev (2010-03-25) [i386-darwin10.2.0]
[ruby-core:28963]

Description

=begin
For some reason, Ruby 1.8 will skip multiple copies of the same method. In case of a recursive function call, the behavior is different from Ruby 1.9 and seems wrong.

Here's the rubyspec I just committed:

 it "returns one entry per call, even for recursive methods" do
   def recurse(n)
     return caller if n <= 0
     recurse(n-1)
   end
   (recurse(3).size - recurse(2).size).should == 1
 end

The following patch doesn't seem to yield any new failure with make test, make test-all, nor the caller specs:

diff --git a/eval.c b/eval.c
index 3407548..65fb970 100644
--- a/eval.c
+++ b/eval.c
@@ -6468,9 +6468,6 @@ backtrace(lev)
}
for (; frame && (n = frame->node); frame = frame->prev) {
if (frame->prev && frame->prev->last_func) {

  •       if (frame->prev->node == n) {
    
  •           if (frame->prev->last_func == frame->last_func) continue;
    
  •       }
          snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
                   n->nd_file, nd_line(n),
                   rb_id2name(frame->prev->last_func));
    

Nobu, can you recall what was the reason for these lines ( r10593 ) ?
=end

Updated by nobu (Nobuyoshi Nakada) over 16 years ago Actions #1

=begin
Hi,

At Thu, 25 Mar 2010 10:38:57 +0900,
Marc-Andre Lafortune wrote in [ruby-core:28963]:

For some reason, Ruby 1.8 will skip multiple copies of the
same method. In case of a recursive function call, the
behavior is different from Ruby 1.9 and seems wrong.

According to the log and ML archive, it was origined from
r8590, and intended to veil implicitly called method names.
e.g.: to make the former to the latter.

$ ruby -e 'p [0].max_by'
-e:1:in max_by': no block given (LocalJumpError) from -e:1:in each'
from -e:1:in `max_by'
from -e:1

$ ruby -e 'p [0].max_by'
-e:1:in `max_by': no block given (LocalJumpError)
from -e:1

But something seems to have changed and it doesn't work
expectedly now.

The following patch doesn't seem to yield any new failure
with make test, make test-all, nor the caller specs:

Seems nice.

Another idea is to reduce same methods like following patch,
but it may cause other issues.


diff --git i/eval.c w/eval.c
index 3407548..159ed0e 100644
--- i/eval.c
+++ w/eval.c
@@ -6437,4 +6437,5 @@ backtrace(lev)
VALUE ary;
NODE *n;

  • int succ = 0;

    ary = rb_ary_new();
    @@ -6467,15 +6468,22 @@ backtrace(lev)
    }
    }

  • for (; frame && (n = frame->node); frame = frame->prev) {
  • for (frame && (n = frame->node); frame = frame->prev) {
  • const char *name = 0;
    if (frame->prev && frame->prev->last_func) {
  •  if (frame->prev->node == n) {
    
  •  if (frame->prev->last_func == frame->last_func) continue;
    
  •  if (frame->prev->node == n && frame->prev->last_func == frame->last_func) {
    
  •  succ++;
    
  •  continue;
     }
    
  •  snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
    
  •       n->nd_file, nd_line(n),
    
  •       rb_id2name(frame->prev->last_func));
    
  •  name = rb_id2name(frame->prev->last_func);
    
    }
  • else {
  •  snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n));
    
  • snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n));
  • if (name) {
  •  long len = strlen(buf);
    
  •  snprintf(buf + len, BUFSIZ - len, ":in `%s'", name);
    
  •  len += strlen(buf + len);
    
  •  if (succ > 0) {
    
  •  snprintf(buf + len, BUFSIZ - len, " (%d levels)", succ + 1);
    
  •  succ = 0;
    
  •  }
    
    }
    rb_ary_push(ary, rb_str_new2(buf));

--
Nobu Nakada

=end

Updated by shyouhei (Shyouhei Urabe) about 16 years ago Actions #2

  • Status changed from Open to Assigned

=begin

=end

Updated by marcandre (Marc-Andre Lafortune) over 14 years ago Actions #3 [ruby-core:45638]

  • Description updated (diff)
  • Status changed from Assigned to Closed
Actions

Also available in: PDF Atom