Skip to content

Instantly share code, notes, and snippets.

@shuujii
Created February 3, 2021 12:45
Show Gist options
  • Select an option

  • Save shuujii/0ac23fa24b0c55b2c602b534d81e4a95 to your computer and use it in GitHub Desktop.

Select an option

Save shuujii/0ac23fa24b0c55b2c602b534d81e4a95 to your computer and use it in GitHub Desktop.

An iv_tbl is not shared when a class includes or prepends an empty module

Example

If a class includes or prepends an anonymous and empty module and then a constant or class variable is added to the module, they cannot be referenced from the class.

m = Module.new
#M = m = Module.new
C = Class.new{include m}
#C = Class.new{prepend m}

m::CONST = 1
puts "C.constants => #{C.constants}"
print "C::CONST(#{'not ' unless C.const_defined?(:CONST)}defined) => "
begin
  puts C::CONST
rescue => e
  puts e
end

m.class_variable_set(:@@cv, 2)
puts "C.class_variables => #{C.class_variables}"
print "C::@@cv(#{'not ' unless C.class_variable_defined?(:@@cv)}defined) => "
begin
  puts C.class_variable_get(:@@cv)
rescue => e
  puts e
end

#=> Actual:
#     C.constants => []
#     C::CONST(not defined) => uninitialized constant C::CONST
#     C.class_variables => []
#     C::@@cv(not defined) => uninitialized class variable @@cv in C

#=> Expected:
#     C.constants => [:CONST]
#     C::CONST(defined) => 1
#     C.class_variables => [:@@cv]
#     C::@@cv(defined) => 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment