From aa381d723c8f400363141d0b781f3d34375aa2bb Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 5 Feb 2007 18:50:35 +0000 Subject: * proc.c: support Binding#eval. * yarvtest/test_eval.rb: add a test for above change. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@11635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 + proc.c | 10 +- yarvtest/test_eval.rb | 434 +++++++++++++++++++++++++------------------------- 3 files changed, 234 insertions(+), 216 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf3b766a1..1e0362ccb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Feb 6 03:47:58 2007 Koichi Sasada + + * proc.c: support Binding#eval. + + * yarvtest/test_eval.rb: add a test for above change. + Tue Feb 6 03:13:33 2007 Koichi Sasada * proc.c: refactoring (remove K&R style, move Binding stuffs from diff --git a/proc.c b/proc.c index f058f7251..0e37b90e4 100644 --- a/proc.c +++ b/proc.c @@ -282,10 +282,13 @@ rb_f_binding(VALUE self) */ static VALUE -bind_eval(int argc, VALUE *argv, VALUE bind) +bind_eval(int argc, VALUE *argv, VALUE bindval) { - UNSUPPORTED(bind_eval); - return Qnil; + VALUE args[4]; + + rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]); + args[1] = bindval; + return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */); } #define PROC_TSHIFT (FL_USHIFT+1) @@ -1584,6 +1587,7 @@ Init_Binding(void) rb_undef_method(CLASS_OF(rb_cBinding), "new"); rb_define_method(rb_cBinding, "clone", binding_clone, 0); rb_define_method(rb_cBinding, "dup", binding_dup, 0); + rb_define_method(rb_cBinding, "eval", bind_eval, -1); rb_define_global_function("binding", rb_f_binding, 0); } diff --git a/yarvtest/test_eval.rb b/yarvtest/test_eval.rb index fc4ac0372..8a82c4cff 100644 --- a/yarvtest/test_eval.rb +++ b/yarvtest/test_eval.rb @@ -1,213 +1,221 @@ -require 'yarvtest/yarvtest' - -class TestEval < YarvTestBase - def test_eval - ae %q{ - eval('1') - } - ae %q{ - eval('a=1; a') - } - ae %q{ - a = 1 - eval('a') - } - end - - def test_eval_with_send - ae %q{ - __send! :eval, %{ - :ok - } - } - ae %q{ - 1.__send! :instance_eval, %{ - :ok - } - } - end - - def test_module_eval - ae %q{ - Const = :top - class C - Const = :C - end - C.module_eval{ - Const - } - } - ae %q{ - Const = :top - class C - Const = :C - end - C.module_eval %{ - Const - } - } if false # TODO: Ruby 1.9 error - - ae %q{ - Const = :top - class C - Const = :C - end - C.class_eval %{ - def m - Const - end - } - C.new.m - } - ae %q{ - Const = :top - class C - Const = :C - end - C.class_eval{ - def m - Const - end - } - C.new.m - } - end - - def test_instance_eval - ae %q{ - 1.instance_eval{ - self - } - } - ae %q{ - 'foo'.instance_eval{ - self - } - } - ae %q{ - class Fixnum - Const = 1 - end - 1.instance_eval %{ - Const - } - } - end - - def test_nest_eval - ae %q{ - Const = :top - class C - Const = :C - end - $nest = false - $ans = [] - def m - $ans << Const - C.module_eval %{ - $ans << Const - Boo = false unless defined? Boo - unless $nest - $nest = true - m - end - } - end - m - $ans - } - ae %q{ - $nested = false - $ans = [] - $pr = proc{ - $ans << self - unless $nested - $nested = true - $pr.call - end - } - class C - def initialize &b - 10.instance_eval(&b) - end - end - C.new(&$pr) - $ans - } - end - - def test_binding - ae %q{ - def m - a = :ok - $b = binding - end - m - eval('a', $b) - } - ae %q{ - def m - a = :ok - $b = binding - end - m - eval('b = :ok2', $b) - eval('[a, b]', $b) - } - ae %q{ - $ans = [] - def m - $b = binding - end - m - $ans << eval(%q{ - $ans << eval(%q{ - a - }, $b) - a = 1 - }, $b) - $ans - } - ae %q{ - Const = :top - class C - Const = :C - def m - binding - end - end - eval('Const', C.new.m) - } - ae %q{ - Const = :top - a = 1 - class C - Const = :C - def m - eval('Const', TOPLEVEL_BINDING) - end - end - C.new.m - } - ae %q{ - class C - $b = binding - end - eval %q{ - def m - :ok - end - }, $b - p C.new.m - } - ae %q{ - b = proc{ - a = :ok - binding - }.call - a = :ng - eval("a", b) - } - end -end - +require 'yarvtest/yarvtest' + +class TestEval < YarvTestBase + def test_eval + ae %q{ + eval('1') + } + ae %q{ + eval('a=1; a') + } + ae %q{ + a = 1 + eval('a') + } + end + + def test_eval_with_send + ae %q{ + __send! :eval, %{ + :ok + } + } + ae %q{ + 1.__send! :instance_eval, %{ + :ok + } + } + end + + def test_module_eval + ae %q{ + Const = :top + class C + Const = :C + end + C.module_eval{ + Const + } + } + ae %q{ + Const = :top + class C + Const = :C + end + C.module_eval %{ + Const + } + } if false # TODO: Ruby 1.9 error + + ae %q{ + Const = :top + class C + Const = :C + end + C.class_eval %{ + def m + Const + end + } + C.new.m + } + ae %q{ + Const = :top + class C + Const = :C + end + C.class_eval{ + def m + Const + end + } + C.new.m + } + end + + def test_instance_eval + ae %q{ + 1.instance_eval{ + self + } + } + ae %q{ + 'foo'.instance_eval{ + self + } + } + ae %q{ + class Fixnum + Const = 1 + end + 1.instance_eval %{ + Const + } + } + end + + def test_nest_eval + ae %q{ + Const = :top + class C + Const = :C + end + $nest = false + $ans = [] + def m + $ans << Const + C.module_eval %{ + $ans << Const + Boo = false unless defined? Boo + unless $nest + $nest = true + m + end + } + end + m + $ans + } + ae %q{ + $nested = false + $ans = [] + $pr = proc{ + $ans << self + unless $nested + $nested = true + $pr.call + end + } + class C + def initialize &b + 10.instance_eval(&b) + end + end + C.new(&$pr) + $ans + } + end + + def test_binding + ae %q{ + def m + a = :ok + $b = binding + end + m + eval('a', $b) + } + ae %q{ + def m + a = :ok + $b = binding + end + m + eval('b = :ok2', $b) + eval('[a, b]', $b) + } + ae %q{ + $ans = [] + def m + $b = binding + end + m + $ans << eval(%q{ + $ans << eval(%q{ + a + }, $b) + a = 1 + }, $b) + $ans + } + ae %q{ + Const = :top + class C + Const = :C + def m + binding + end + end + eval('Const', C.new.m) + } + ae %q{ + Const = :top + a = 1 + class C + Const = :C + def m + eval('Const', TOPLEVEL_BINDING) + end + end + C.new.m + } + ae %q{ + class C + $b = binding + end + eval %q{ + def m + :ok + end + }, $b + p C.new.m + } + ae %q{ + b = proc{ + a = :ok + binding + }.call + a = :ng + eval("a", b) + } + ae %q{ + class C + def foo + binding + end + end + C.new.foo.eval("self.class.to_s") + } + end +end + -- cgit