aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--test/ruby/test_backtrace.rb34
-rw-r--r--vm_eval.c30
3 files changed, 67 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e845fb0e8..bdd22e8c9d 100644
--- a/ChangeLog
+++ b/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
diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb
index 9f2d4c465c..c35b95c9e1 100644
--- a/test/ruby/test_backtrace.rb
+++ b/test/ruby/test_backtrace.rb
@@ -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
diff --git a/vm_eval.c b/vm_eval.c
index cd83d42847..0160b66af6 100644
--- a/vm_eval.c
+++ b/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