summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-class-ext
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-07-17 10:35:41 +0900
committerGitHub <[email protected]>2019-07-17 10:35:41 +0900
commitd605b72c1d6fa4564a0a5e88535504b6850463b5 (patch)
tree774fc0de56002abb3bb2b1c3387ff08f91876d17 /mrbgems/mruby-class-ext
parent2af92d0ebcbeca6d3d85a27c8193273080a63090 (diff)
parent9af3b7c6258de327218dd04e69d76ae68caf17b1 (diff)
downloadmruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.tar.gz
mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.zip
Merge branch 'master' into i110/inspect-recursion
Diffstat (limited to 'mrbgems/mruby-class-ext')
-rw-r--r--mrbgems/mruby-class-ext/mrblib/module.rb89
-rw-r--r--mrbgems/mruby-class-ext/src/class.c3
-rw-r--r--mrbgems/mruby-class-ext/test/module.rb56
3 files changed, 145 insertions, 3 deletions
diff --git a/mrbgems/mruby-class-ext/mrblib/module.rb b/mrbgems/mruby-class-ext/mrblib/module.rb
new file mode 100644
index 000000000..301585187
--- /dev/null
+++ b/mrbgems/mruby-class-ext/mrblib/module.rb
@@ -0,0 +1,89 @@
+class Module
+
+ ##
+ # call-seq:
+ # mod < other -> true, false, or nil
+ #
+ # Returns true if `mod` is a subclass of `other`. Returns
+ # <code>nil</code> if there's no relationship between the two.
+ # (Think of the relationship in terms of the class definition:
+ # "class A < B" implies "A < B".)
+ #
+ def <(other)
+ if self.equal?(other)
+ false
+ else
+ self <= other
+ end
+ end
+
+ ##
+ # call-seq:
+ # mod <= other -> true, false, or nil
+ #
+ # Returns true if `mod` is a subclass of `other` or
+ # is the same as `other`. Returns
+ # <code>nil</code> if there's no relationship between the two.
+ # (Think of the relationship in terms of the class definition:
+ # "class A < B" implies "A < B".)
+ def <=(other)
+ raise TypeError, 'compared with non class/module' unless other.is_a?(Module)
+ if self.ancestors.include?(other)
+ return true
+ elsif other.ancestors.include?(self)
+ return false
+ end
+ end
+
+ ##
+ # call-seq:
+ # mod > other -> true, false, or nil
+ #
+ # Returns true if `mod` is an ancestor of `other`. Returns
+ # <code>nil</code> if there's no relationship between the two.
+ # (Think of the relationship in terms of the class definition:
+ # "class A < B" implies "B > A".)
+ #
+ def >(other)
+ if self.equal?(other)
+ false
+ else
+ self >= other
+ end
+ end
+
+ ##
+ # call-seq:
+ # mod >= other -> true, false, or nil
+ #
+ # Returns true if `mod` is an ancestor of `other`, or the
+ # two modules are the same. Returns
+ # <code>nil</code> if there's no relationship between the two.
+ # (Think of the relationship in terms of the class definition:
+ # "class A < B" implies "B > A".)
+ #
+ def >=(other)
+ raise TypeError, 'compared with non class/module' unless other.is_a?(Module)
+ return other < self
+ end
+
+ ##
+ # call-seq:
+ # module <=> other_module -> -1, 0, +1, or nil
+ #
+ # Comparison---Returns -1, 0, +1 or nil depending on whether `module`
+ # includes `other_module`, they are the same, or if `module` is included by
+ # `other_module`.
+ #
+ # Returns `nil` if `module` has no relationship with `other_module`, if
+ # `other_module` is not a module, or if the two values are incomparable.
+ #
+ def <=>(other)
+ return 0 if self.equal?(other)
+ return nil unless other.is_a?(Module)
+ cmp = self < other
+ return -1 if cmp
+ return 1 unless cmp.nil?
+ return nil
+ end
+end
diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c
index 705db9949..fdd56bcc3 100644
--- a/mrbgems/mruby-class-ext/src/class.c
+++ b/mrbgems/mruby-class-ext/src/class.c
@@ -5,8 +5,7 @@
static mrb_value
mrb_mod_name(mrb_state *mrb, mrb_value self)
{
- mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self));
- return mrb_nil_p(name)? name : mrb_str_dup(mrb, name);
+ return mrb_class_path(mrb, mrb_class_ptr(self));
}
static mrb_value
diff --git a/mrbgems/mruby-class-ext/test/module.rb b/mrbgems/mruby-class-ext/test/module.rb
index ed6713aac..52e04ab37 100644
--- a/mrbgems/mruby-class-ext/test/module.rb
+++ b/mrbgems/mruby-class-ext/test/module.rb
@@ -1,3 +1,57 @@
+assert 'Module#<' do
+ a = Class.new
+ b = Class.new(a)
+ c = Class.new(a)
+ d = Module.new
+ e = Class.new { include d }
+ f = Module.new { include d }
+
+ # compare class to class
+ assert_true b < a
+ assert_false b < b
+ assert_false a < b
+ assert_nil c < b
+
+ # compare class to module
+ assert_true e < d
+ assert_false d < e
+ assert_nil a < d
+
+ # compare module to module
+ assert_true f < d
+ assert_false f < f
+ assert_false d < f
+
+ assert_raise(TypeError) { a < Object.new }
+end
+
+assert 'Module#<=' do
+ a = Class.new
+ b = Class.new(a)
+ c = Class.new(a)
+ d = Module.new
+ e = Class.new { include d }
+ f = Module.new { include d }
+
+ # compare class to class
+ assert_true b <= a
+ assert_true b <= b
+ assert_false a <= b
+ assert_nil c <= b
+
+ # compare class to module
+ assert_true e <= d
+ assert_false d <= e
+ assert_nil a <= d
+
+ # compare module to module
+ assert_true f <= d
+ assert_true f <= f
+ assert_false d <= f
+
+ assert_raise(TypeError) { a <= Object.new }
+end
+
assert 'Module#name' do
module Outer
class Inner; end
@@ -26,7 +80,7 @@ end
assert 'Module#singleton_class?' do
mod = Module.new
cls = Class.new
- scl = cls.singleton_class
+ scl = (class <<cls; self; end)
assert_false mod.singleton_class?
assert_false cls.singleton_class?