Project

General

Profile

Bug #7475

Unexpected behavior of Module#append_features on singleton class

Added by ernie (Ernie Miller) over 6 years ago. Updated 8 days ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin12.2.0]
[ruby-core:50356]

Description

=begin
A more involved explanation is available at ((URL:http://erniemiller.org/2012/11/29/ruby-tidbit-include-vs-extend-with-module-class-variables/))

In short, the handling of class variables (and constants) when a module is extended vs included is not as expected.

Example:

module Foo
  @@foo = 'foo'
end

class Bar
  include Foo
end

class Baz
  extend Foo
end

Bar.class_variable_get :@@foo # => "foo"
Baz.singleton_class.class_variable_get :@@foo # => NameError: uninitialized class variable @@foo in Class

We would expect constant and class variable lookup on the singleton class to work, but it doesn't. Both Rubinius and JRuby seem to behave as expected in this case.

Thanks!
=end

History

Updated by ernie (Ernie Miller) over 6 years ago

Another quick set of observations from this morning:

class Baz
  class << self
    Const = 'Const'
    @@foo = 'foo'
  end
end

Baz.class_variables.inspect # => [:@@foo]
Baz.singleton_class.class_variables.inspect # => []
Baz.singleton_class.class_variable_get :@@foo # => 'foo' ???
Baz.const_get(:Const, false) rescue "Nope." # => 'Nope.'
Baz.singleton_class.const_get(:Const, false) rescue "Nope." # => Const

# Let's try setting it explicitly.
Baz.singleton_class.class_variable_set :@@foo, 'foo'
Baz.singleton_class.class_variables.inspect # => [] -- still "empty"

However, if we extend Foo on Baz, vs opening the singleton class with "class << self", we can class_variable_set on the singleton and see it show up in the list of class variables, vs being empty.

All of this is to say that I think some unexpected weirdness is going on in rb_include_module and/or include_class_new.

Updated by ko1 (Koichi Sasada) over 6 years ago

  • Assignee set to matz (Yukihiro Matsumoto)
  • Target version changed from 1.9.3 to 2.6

Matz, could you check it?

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Description updated (diff)
#4

Updated by naruse (Yui NARUSE) over 1 year ago

  • Target version deleted (2.6)

Updated by jeremyevans0 (Jeremy Evans) 8 days ago

  • Status changed from Open to Closed

I believe this is not a bug, it is expected behavior. Class variable lookup for singleton classes is different from regular classes. Class variable lookup for singleton classes is (with example class A):

  • Singleton Class (A.singleton_class)
  • All Ancestors of Class (A.ancestors)

Note that this does not include modules included in the singleton class.

Class variable access is different for singleton classes because class variable access from the singleton class should access class variables in the class itself.

Class variable lookup could certainly be changed to include modules included in the singleton class, but that would be a separate feature request, and we would have to decide if we want to only include modules before the superclass's singleton class, or all modules and singleton classes before Class. Please submit a feature request if you would like to change class variable lookup.

Also available in: Atom PDF