mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* proc.c: support Binding#eval.
* yarvtest/test_eval.rb: add a test for above change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0d70d88643
commit
a4a8101965
3 changed files with 234 additions and 216 deletions
|
@ -1,3 +1,9 @@
|
|||
Tue Feb 6 03:47:58 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* proc.c: support Binding#eval.
|
||||
|
||||
* yarvtest/test_eval.rb: add a test for above change.
|
||||
|
||||
Tue Feb 6 03:13:33 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* proc.c: refactoring (remove K&R style, move Binding stuffs from
|
||||
|
|
10
proc.c
10
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue