Bug #2788
closed
nil.instance_eval pushes nil onto cref
Added by shugo (Shugo Maeda) almost 15 years ago.
Updated over 12 years ago.
Description
=begin
A singleton class definition of nil pushes NilClass onto cref.
It is reasonable because NilClass has nil as the only instance.
However, nil.instance_eval pushes nil onto cref, which means that method definitions are not permitted in that context.
defiant:ruby$ ruby-trunk -ve 'class <<nil; def foo; puts "foo" end; end; nil.foo'
ruby 1.9.2dev (2010-02-18 trunk 26704) [i686-linux]
foo
defiant:ruby$ ruby-trunk -ve 'nil.instance_eval {|i| def foo; puts "foo" end }; nil.foo'
ruby 1.9.2dev (2010-02-18 trunk 26704) [i686-linux]
-e:1:in block in <main>': no class/module to add method (TypeError) from -e:1:in
instance_eval'
from -e:1:in `'
The behavior is the same in Ruby 1.8.7.
Is it intended or a bug?
=end
- Project changed from Ruby to Ruby master
- Category changed from core to core
- Assignee changed from matz (Yukihiro Matsumoto) to ko1 (Koichi Sasada)
- Target version set to 2.0.0
Behavior is intended, as per tests in bootstraptest/test_eval.rb and [ruby-core:16808], but I'm don't think it's the right way to go, since nil
, true
and false
do have singleton classes.
Koichi, do you agree the following patch would be good?
diff --git a/vm_eval.c b/vm_eval.c
index aa32621..dfd4588 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1346,7 +1346,7 @@ rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
{
VALUE klass;
- if (SPECIAL_CONST_P(self)) {
- if (FIXNUM_P(self) || SYMBOL_P(self)) {
klass = Qnil;
}
else {
@@ -1378,7 +1378,7 @@ rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
{
VALUE klass;
- if (SPECIAL_CONST_P(self)) {
- if (FIXNUM_P(self) || SYMBOL_P(self)) {
klass = Qnil;
}
else {
diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb
index c347d50..e25cc260 100644
--- a/bootstraptest/test_eval.rb
+++ b/bootstraptest/test_eval.rb
@@ -264,24 +264,18 @@ assert_equal 'ok', %q{
}, '[ruby-core:16794]'
assert_equal 'ok', %q{
- begin
- nil.instance_eval {
-
def a() :a end
- }
- rescue TypeError
- :ok
- end
-}, '[ruby-core:16796]'
- nil.instance_eval {
- def defd_using_instance_eval() :ok end
- }
- nil.defd_using_instance_eval
+}, '[ruby-core:28324]'
assert_equal 'ok', %q{
- begin
- nil.instance_exec {
-
def a() :a end
- }
- rescue TypeError
- :ok
- end
-}, '[ruby-core:16796]'
- nil.instance_exec {
- def defd_using_instance_exec() :ok end
- }
- nil.defd_using_instance_exec
+}, '[ruby-core:28324]'
assert_normal_exit %q{
eval("", method(:proc).call {}.binding)
test-all also points out that @@class_level_variable
would then refer to NilClass
/FalseClass
/TrueClass
's class variables, contrary to other singleton classes. This would be consistent with class << nil
vs class << my_string
.
- Assignee changed from ko1 (Koichi Sasada) to matz (Yukihiro Matsumoto)
I'm so sorry to miss your ticket for long time.
Always I get confusing about instance eval with special variables (nil, false, etc).
Matz (shugo-san is specialist?), could you determine the specification?
- Assignee changed from matz (Yukihiro Matsumoto) to nobu (Nobuyoshi Nakada)
- Priority changed from 3 to Normal
ko1 (Koichi Sasada) wrote:
nobu has patach.
Does he have a Hebrew niqqud vowel sign?
Aside from the joke, why not apply the patch, Nobu?
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r36647.
Shugo, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
method in instance_eval
- class.c (rb_special_singleton_class_of): utility function.
- vm_eval.c (eval_under): special deal for class variable scope with
instance_eval.
- vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow method
definition in instance_eval of special constants. [ruby-core:28324]
[Bug #2788]
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0