Project

General

Profile

Actions

Bug #3011

closed

caller for recursive function

Added by marcandre (Marc-Andre Lafortune) over 12 years ago. Updated over 10 years ago.

Status:
Closed
Priority:
Normal
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

Actions #1

Updated by nobu (Nobuyoshi Nakada) over 12 years ago

=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
[ruby-dev:26245] * eva..." href="/projects/ruby-18/repository/25/revisions/8590">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

Actions #2

Updated by shyouhei (Shyouhei Urabe) about 12 years ago

  • Status changed from Open to Assigned

=begin

=end

Updated by marcandre (Marc-Andre Lafortune) over 10 years ago

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

Also available in: Atom PDF