mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm_eval.c (rb_f_caller): caller() method accepts second optional
argument `n' which specify how many frames should return. For example, `caller(0, 1)' returns only one frame information which calls caller() method. If there are less than n frame information, then all frame information are returned. If n is 0, then always return []. This fix is part of [ruby-dev:42345] [Ruby 1.9-Feature#3917]. However, performance and features are not enough. RDoc is also not available. * test/ruby/test_backtrace.rb: add a test for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35792 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a5f190615e
commit
4258db7954
3 changed files with 67 additions and 11 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
Fri May 25 19:51:36 2012 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm_eval.c (rb_f_caller): caller() method accepts second optional
|
||||
argument `n' which specify how many frames should return.
|
||||
For example, `caller(0, 1)' returns only one frame information
|
||||
which calls caller() method. If there are less than n frame
|
||||
information, then all frame information are returned. If n is 0,
|
||||
then always return [].
|
||||
This fix is part of [ruby-dev:42345] [Ruby 1.9-Feature#3917].
|
||||
However, performance and features are not enough.
|
||||
RDoc is also not available.
|
||||
|
||||
* test/ruby/test_backtrace.rb: add a test for above.
|
||||
|
||||
Fri May 25 17:05:07 2012 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm.c (oldbt_init, vm_backtrace_str_ary): arg->data should
|
||||
|
|
|
@ -40,7 +40,7 @@ class TestBacktrace < Test::Unit::TestCase
|
|||
rec[n-1]
|
||||
}
|
||||
else
|
||||
max.times{|i|
|
||||
(max*3).times{|i|
|
||||
total_size = caller(0).size
|
||||
c = caller(i)
|
||||
if c
|
||||
|
@ -53,5 +53,35 @@ class TestBacktrace < Test::Unit::TestCase
|
|||
rec[max]
|
||||
}.resume
|
||||
end
|
||||
end
|
||||
|
||||
def test_caller_lev_and_n
|
||||
m = 10
|
||||
rec = lambda{|n|
|
||||
if n < 0
|
||||
(m*6).times{|lev|
|
||||
(m*6).times{|n|
|
||||
t = caller(0).size
|
||||
r = caller(lev, n)
|
||||
r = r.size if r.respond_to? :size
|
||||
|
||||
# STDERR.puts [t, lev, n, r].inspect
|
||||
if n == 0
|
||||
assert_equal(0, r, [t, lev, n, r].inspect)
|
||||
elsif t < lev
|
||||
assert_equal(nil, r, [t, lev, n, r].inspect)
|
||||
else
|
||||
if t - lev > n
|
||||
assert_equal(n, r, [t, lev, n, r].inspect)
|
||||
else
|
||||
assert_equal(t - lev, r, [t, lev, n, r].inspect)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
else
|
||||
rec[n-1]
|
||||
end
|
||||
}
|
||||
rec[m]
|
||||
end
|
||||
end
|
||||
|
|
30
vm_eval.c
30
vm_eval.c
|
@ -1609,19 +1609,31 @@ rb_catch_obj(VALUE tag, VALUE (*func)(), VALUE data)
|
|||
static VALUE
|
||||
rb_f_caller(int argc, VALUE *argv)
|
||||
{
|
||||
VALUE level;
|
||||
int lev;
|
||||
VALUE level, vn;
|
||||
int lev, n;
|
||||
|
||||
rb_scan_args(argc, argv, "01", &level);
|
||||
rb_scan_args(argc, argv, "02", &level, &vn);
|
||||
|
||||
if (NIL_P(level))
|
||||
lev = 1;
|
||||
else
|
||||
lev = NUM2INT(level);
|
||||
if (lev < 0)
|
||||
lev = NIL_P(level) ? 1 : NUM2INT(level);
|
||||
|
||||
if (NIL_P(vn)) {
|
||||
n = 0;
|
||||
}
|
||||
else {
|
||||
n = NUM2INT(vn);
|
||||
if (n == 0) {
|
||||
return rb_ary_new();
|
||||
}
|
||||
}
|
||||
|
||||
if (lev < 0) {
|
||||
rb_raise(rb_eArgError, "negative level (%d)", lev);
|
||||
}
|
||||
if (n < 0) {
|
||||
rb_raise(rb_eArgError, "negative n (%d)", n);
|
||||
}
|
||||
|
||||
return vm_backtrace_str_ary(GET_THREAD(), lev+1, 0);
|
||||
return vm_backtrace_str_ary(GET_THREAD(), lev+1, n);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue