lib/kind.rb in kind-0.2.0 vs lib/kind.rb in kind-0.3.0

- old
+ new

@@ -7,145 +7,117 @@ def initialize(klass, object) super("#{object.inspect} expected to be a kind of #{klass}") end end - module Of - def self.call(klass, object) - return object if object.is_a?(klass) + module Is + def self.call(expected, value) + expected_mod = Kind::Of.Module(expected) + mod = Kind::Of.Module(value) - raise Kind::Error.new(klass, object) + mod <= expected_mod || false end - def self.Class(object) - self.call(::Class, object) + def self.Class(value) + value.is_a?(::Class) end - def self.Module(object) - self.call(::Module, object) + def self.Module(value) + value == ::Module || (value.is_a?(::Module) && !self.Class(value)) end + end - def self.Boolean(object = nil) - return Kind::Of::Boolean if object.nil? + class Checker + attr_reader :type - return object if object.is_a?(::TrueClass) || object.is_a?(::FalseClass) + def initialize(type) + @type = type + end - raise Kind::Error.new('Boolean'.freeze, object) + def class?(value) + Kind::Is.call(@type, value) end - module Boolean - def self.class?(value) - Kind.is.Boolean(value) - end + def instance?(value) + value.is_a?(@type) + end - def self.instance?(value) - value.is_a?(TrueClass) || value.is_a?(FalseClass) - end - - def self.or_nil(value) - return value if instance?(value) - end + def or_nil(value) + return value if instance?(value) end + end - def self.Lambda(object = nil) - return Kind::Of::Lambda if object.nil? + module Of + def self.call(klass, object) + return object if object.is_a?(klass) - return object if object.is_a?(::Proc) && object.lambda? - - raise Kind::Error.new('Lambda'.freeze, object) + raise Kind::Error.new(klass, object) end - module Lambda - def self.class?(value) - Kind.is.Proc(value) - end + def self.Class(object = nil) + return Class if object.nil? - def self.instance?(value) - value.is_a?(::Proc) && value.lambda? - end + self.call(::Class, object) + end - def self.or_nil(value) - return value if instance?(value) + const_set(:Class, ::Class.new(Checker) do + def instance?(value) + Kind::Is.Class(value) end - end - end - module Is - def self.call(expected, value) - expected_klass, klass = Kind.of.Module(expected), Kind.of.Module(value) + alias class? instance? + end.new(::Class).freeze) - klass <= expected_klass || false - end + def self.Module(object = nil) + return Module if object.nil? - def self.Class(value) - value.is_a?(::Class) + self.call(::Module, object) end - def self.Module(value) - value == Module || (value.is_a?(::Module) && !self.Class(value)) - end + const_set(:Module, ::Class.new(Checker) do + def instance?(value) + Kind::Is.Module(value) + end - def self.Boolean(value) - klass = Kind.of.Class(value) - klass <= TrueClass || klass <= FalseClass - end + alias class? instance? + end.new(::Module).freeze) end - def self.of; Of; end - def self.is; Is; end - module Types extend self KIND_OF = <<-RUBY - def self.%{klass}(object = nil) - return Kind::Of::%{klass} if object.nil? + def self.%{name}(object = nil) + return Kind::Of::%{name} if object.nil? - Kind::Of.call(::%{klass}, object) + Kind::Of.call(::%{name}, object) end RUBY KIND_IS = <<-RUBY - def self.%{klass}(value) - Kind::Is.call(::%{klass}, value) + def self.%{name}(value) + Kind::Is.call(::%{name}, value) end RUBY - KIND_OF_MODULE = <<-RUBY - def self.class?(value) - Kind::Is.call(::%{klass}, value) - end + private_constant :KIND_OF, :KIND_IS - def self.instance?(value) - value.is_a?(::%{klass}) - end + def add(mod) + name = Kind.of.Module(mod).name - def self.or_nil(value) - return value if instance?(value) + unless Of.respond_to?(name) + Of.instance_eval(KIND_OF % { name: name }) + Of.const_set(name, Checker.new(mod).freeze) end - RUBY - private_constant :KIND_OF, :KIND_IS, :KIND_OF_MODULE - - def add(klass) - klass_name = Kind.of.Module(klass).name - - return if Of.respond_to?(klass_name) - - Of.instance_eval(KIND_OF % { klass: klass_name }) - - type_module = Module.new - type_module.instance_eval(KIND_OF_MODULE % { klass: klass_name }) - - Of.const_set(klass_name, type_module) - - return if Is.respond_to?(klass_name) - - Is.instance_eval(KIND_IS % { klass: klass_name }) + Is.instance_eval(KIND_IS % { name: name }) unless Is.respond_to?(name) end end + def self.is; Is; end + def self.of; Of; end + # Classes [ String, Symbol, Numeric, Integer, Float, Regexp, Time, Array, Range, Hash, Struct, Enumerator, Method, Proc, @@ -154,6 +126,57 @@ # Modules [ Enumerable, Comparable ].each { |klass| Types.add(klass) } + + # --------------------- # + # Special type checkers # + # --------------------- # + + module Is + def self.Boolean(value) + klass = Kind.of.Class(value) + klass <= TrueClass || klass <= FalseClass + end + end + + module Of + # -- Boolean + + def self.Boolean(object = nil) + return Kind::Of::Boolean if object.nil? + + return object if object.is_a?(::TrueClass) || object.is_a?(::FalseClass) + + raise Kind::Error.new('Boolean'.freeze, object) + end + + const_set(:Boolean, ::Class.new(Checker) do + def class?(value) + Kind.is.Boolean(value) + end + + def instance?(value) + value.is_a?(TrueClass) || value.is_a?(FalseClass) + end + end.new([TrueClass, FalseClass].freeze).freeze) + + # -- Lambda + + def self.Lambda(object = nil) + return Kind::Of::Lambda if object.nil? + + return object if object.is_a?(::Proc) && object.lambda? + + raise Kind::Error.new('Lambda'.freeze, object) + end + + const_set(:Lambda, ::Class.new(Checker) do + def instance?(value) + value.is_a?(::Proc) && value.lambda? + end + end.new(::Proc).freeze) + end + + private_constant :Checker end