2015-12-16 00:07:31 -05:00
|
|
|
# frozen_string_literal: false
|
* test/ruby/test_metaclass.rb: new test case for metaclass hierarchy.
* class.c (make_metametaclass): new function. extracted from
rb_make_metaclass.
* class.c (rb_make_metaclass): uses make_metametaclass when called for a
metaclass.
* class.c (rb_singleton_class): creates a meta^(n+2)-class in
addition to a meta^(n+1)-class when called for a meta^(n)-class.
This is because the returned meta^(n+1) class must acts as an instance of
Class, metaclass of Class, ..., meta^(n+1)-class of Class,
Module, metaclass of Module, ..., meta^(n+1)-class of Module,
Object, metaclass of Object, ..., meta^(n+2)-class of Object,
BasicObject, metaclass of BasicObject, ..., meta^(n+2)-class of
and BasicObject even when Class, Module, Object or BasicObject has
not have its meta^(i)-class yet.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20747 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-12-15 01:23:43 -05:00
|
|
|
require 'test/unit'
|
|
|
|
|
|
|
|
class TestMetaclass < Test::Unit::TestCase
|
|
|
|
class Foo; end
|
|
|
|
class Bar < Foo; end
|
|
|
|
class Baz; end
|
|
|
|
|
|
|
|
def setup
|
|
|
|
Object.class_eval do
|
|
|
|
def method_o; end
|
|
|
|
end
|
|
|
|
Module.class_eval do
|
|
|
|
def method_m; end
|
|
|
|
end
|
|
|
|
Class.class_eval do
|
|
|
|
def method_c; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
def teardown
|
|
|
|
Object.class_eval do
|
|
|
|
remove_method :method_o rescue nil
|
|
|
|
end
|
|
|
|
Module.class_eval do
|
|
|
|
remove_method :method_m rescue nil
|
|
|
|
end
|
|
|
|
Class.class_eval do
|
|
|
|
remove_method :method_c rescue nil
|
|
|
|
end
|
|
|
|
Object.class_eval do
|
|
|
|
class << self
|
|
|
|
remove_method :class_method_o rescue nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Module.class_eval do
|
|
|
|
class << self
|
|
|
|
remove_method :class_method_m rescue nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Class.class_eval do
|
|
|
|
class << self
|
|
|
|
remove_method :class_method_c rescue nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Object.class_eval do
|
|
|
|
class << self
|
|
|
|
class << self
|
|
|
|
remove_method :metaclass_method_o rescue nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Module.class_eval do
|
|
|
|
class << self
|
|
|
|
class << self
|
|
|
|
remove_method :metaclass_method_m rescue nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Class.class_eval do
|
|
|
|
class << self
|
|
|
|
class << self
|
|
|
|
remove_method :metaclass_method_c rescue nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_metaclass
|
|
|
|
class << Object
|
|
|
|
def class_method_o; end
|
|
|
|
end
|
|
|
|
class << Foo
|
|
|
|
def class_method_f; end
|
|
|
|
end
|
|
|
|
class << Baz
|
|
|
|
def class_method_b; end
|
|
|
|
end
|
|
|
|
assert_nothing_raised{ Bar.method_o }
|
|
|
|
assert_nothing_raised{ Bar.method_m }
|
|
|
|
assert_nothing_raised{ Bar.method_c }
|
|
|
|
assert_nothing_raised{ Bar.class_method_o }
|
|
|
|
assert_nothing_raised{ Bar.class_method_f }
|
|
|
|
assert_raise(NoMethodError){ Bar.class_method_b }
|
|
|
|
|
|
|
|
class << Module
|
|
|
|
def class_method_m; end
|
|
|
|
end
|
|
|
|
class << Class
|
|
|
|
def class_method_c; end
|
|
|
|
end
|
|
|
|
class << Object
|
|
|
|
class << self
|
|
|
|
def metaclass_method_o; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class << Foo
|
|
|
|
class << self
|
|
|
|
def metaclass_method_f; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class << Baz
|
|
|
|
class << self
|
|
|
|
def metaclass_method_b; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
metaclass_of_bar = class << Bar; self end
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.method_o }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.method_m }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.method_c }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.class_method_o }
|
|
|
|
assert_raise(NoMethodError){ metaclass_of_bar.class_method_f }
|
|
|
|
assert_raise(NoMethodError){ metaclass_of_bar.class_method_b }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.class_method_m }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.class_method_c }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.metaclass_method_o }
|
|
|
|
assert_nothing_raised{ metaclass_of_bar.metaclass_method_f }
|
|
|
|
assert_raise(NoMethodError){ metaclass_of_bar.metaclass_method_b }
|
|
|
|
|
|
|
|
class << Module
|
|
|
|
class << self
|
|
|
|
def metaclass_method_m; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class << Class
|
|
|
|
class << self
|
|
|
|
def metaclass_method_c; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class << Object
|
|
|
|
class << self
|
|
|
|
class << self
|
|
|
|
def metametaclass_method_o; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class << Foo
|
|
|
|
class << self
|
|
|
|
class << self
|
|
|
|
def metametaclass_method_f; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class << Baz
|
|
|
|
class << self
|
|
|
|
class << self
|
|
|
|
def metametaclass_method_b; end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
metametaclass_of_bar = class << metaclass_of_bar; self end
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.method_o }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.method_m }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.method_c }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.class_method_o }
|
|
|
|
assert_raise(NoMethodError){ metametaclass_of_bar.class_method_f }
|
|
|
|
assert_raise(NoMethodError){ metametaclass_of_bar.class_method_b }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.class_method_m }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.class_method_c }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.metaclass_method_o }
|
|
|
|
assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_f }
|
|
|
|
assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_b }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.metaclass_method_m }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.metaclass_method_c }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.metametaclass_method_o }
|
|
|
|
assert_nothing_raised{ metametaclass_of_bar.metametaclass_method_f }
|
|
|
|
assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_b }
|
|
|
|
end
|
|
|
|
end
|