Bug #2788

nil.instance_eval pushes nil onto cref

Added by Shugo Maeda over 5 years ago. Updated almost 3 years ago.

[ruby-core:28324]
Status:Closed
Priority:Normal
Assignee:Nobuyoshi Nakada
ruby -v:ruby 1.9.2dev (2010-02-18 trunk 26704) [i686-linux] Backport:

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 <': 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

Associated revisions

Revision 36647
Added by Nobuyoshi Nakada almost 3 years ago

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. [Bug #2788]

Revision 36647
Added by Nobuyoshi Nakada almost 3 years ago

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. [Bug #2788]

History

#1 Updated by Akira Tanaka about 4 years ago

  • Project changed from Ruby to Ruby trunk
  • Category changed from core to core

#2 Updated by Marc-Andre Lafortune over 3 years ago

  • Assignee changed from Yukihiro Matsumoto to Koichi Sasada
  • Target version set to 2.0.0

Behavior is intended, as per tests in bootstraptest/test_eval.rb and , 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{
    }, ''

assert_equal 'ok', %q{
- begin
- nil.instance_eval {
- def a() :a end
- }
- rescue TypeError
- :ok
- end
-}, ''
+ nil.instance_eval {
+ def defd_using_instance_eval() :ok end
+ }
+ nil.defd_using_instance_eval
+}, ''

assert_equal 'ok', %q{
- begin
- nil.instance_exec {
- def a() :a end
- }
- rescue TypeError
- :ok
- end
-}, ''
+ nil.instance_exec {
+ def defd_using_instance_exec() :ok end
+ }
+ nil.defd_using_instance_exec
+}, ''

assert_normal_exit %q{
eval("", method(:proc).call {}.binding)

#3 Updated by Marc-Andre Lafortune over 3 years ago

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.

#4 Updated by Koichi Sasada about 3 years ago

  • Assignee changed from Koichi Sasada to 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?

#5 Updated by Koichi Sasada about 3 years ago

  • Assignee changed from Yukihiro Matsumoto to Nobuyoshi Nakada

nobu has patach.

#6 Updated by Shugo Maeda almost 3 years ago

  • 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?

#7 Updated by Usaku NAKAMURA almost 3 years ago

Hello,

In message " [ruby-trunk - Bug #2788] nil.instance_eval pushes nil onto cref"
on Aug.06,2012 17:15:16, redmine@ruby-lang.org wrote:

Aside from the joke, why not apply the patch, Nobu?

Wait until he drives his time machine.

Regards,
--
U.Nakamura usa@garbagecollect.jp

#8 Updated by Nobuyoshi Nakada almost 3 years ago

  • 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. [Bug #2788]

Also available in: Atom PDF