Project

General

Profile

Actions

Bug #2788

closed

nil.instance_eval pushes nil onto cref

Added by shugo (Shugo Maeda) over 14 years ago. Updated over 12 years ago.

Status:
Closed
Target version:
ruby -v:
ruby 1.9.2dev (2010-02-18 trunk 26704) [i686-linux]
Backport:
[ruby-core:28324]

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

Actions #1

Updated by akr (Akira Tanaka) over 13 years ago

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

Updated by marcandre (Marc-Andre Lafortune) over 12 years ago

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

Updated by marcandre (Marc-Andre Lafortune) over 12 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.

Updated by ko1 (Koichi Sasada) over 12 years ago

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

Actions #5

Updated by ko1 (Koichi Sasada) over 12 years ago

  • Assignee changed from matz (Yukihiro Matsumoto) to nobu (Nobuyoshi Nakada)

nobu has patach.

Actions #6

Updated by shugo (Shugo Maeda) over 12 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?

Updated by usa (Usaku NAKAMURA) over 12 years ago

Hello,

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

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

Wait until he drives his time machine.

Regards,

U.Nakamura

Actions #8

Updated by nobu (Nobuyoshi Nakada) over 12 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. [ruby-core:28324]
    [Bug #2788]
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0