y_support 2.1.5 → 2.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +675 -0
- data/Rakefile +1 -1
- data/lib/y_support/abstract_algebra.rb +1 -0
- data/lib/y_support/all.rb +1 -0
- data/lib/y_support/core_ext/array.rb +2 -2
- data/lib/y_support/core_ext/class/misc.rb +2 -3
- data/lib/y_support/core_ext/class.rb +2 -2
- data/lib/y_support/core_ext/enumerable/misc.rb +1 -1
- data/lib/y_support/core_ext/enumerable.rb +2 -2
- data/lib/y_support/core_ext/hash/misc.rb +26 -39
- data/lib/y_support/core_ext/hash.rb +2 -2
- data/lib/y_support/core_ext/module/misc.rb +39 -1
- data/lib/y_support/core_ext/module.rb +2 -2
- data/lib/y_support/core_ext/numeric/misc.rb +0 -2
- data/lib/y_support/core_ext/numeric.rb +2 -2
- data/lib/y_support/core_ext/object/inspection.rb +0 -2
- data/lib/y_support/core_ext/object/misc.rb +31 -16
- data/lib/y_support/core_ext/object.rb +3 -3
- data/lib/y_support/core_ext/string/misc.rb +7 -7
- data/lib/y_support/core_ext/string.rb +2 -2
- data/lib/y_support/core_ext/symbol/misc.rb +2 -3
- data/lib/y_support/core_ext/symbol.rb +2 -2
- data/lib/y_support/core_ext.rb +0 -2
- data/lib/y_support/inert_recorder.rb +1 -1
- data/lib/y_support/kde.rb +1 -0
- data/lib/y_support/name_magic/array.rb +27 -7
- data/lib/y_support/name_magic/class_methods.rb +52 -58
- data/lib/y_support/name_magic/hash.rb +18 -4
- data/lib/y_support/name_magic/namespace_methods.rb +241 -174
- data/lib/y_support/name_magic.rb +82 -38
- data/lib/y_support/null_object.rb +8 -7
- data/lib/y_support/respond_to.rb +1 -2
- data/lib/y_support/stdlib_ext/matrix/misc.rb +0 -2
- data/lib/y_support/stdlib_ext/matrix.rb +2 -2
- data/lib/y_support/stdlib_ext.rb +1 -0
- data/lib/y_support/try.rb +1 -1
- data/lib/y_support/typing/array/typing.rb +45 -4
- data/lib/y_support/typing/array.rb +1 -1
- data/lib/y_support/typing/enumerable/typing.rb +26 -28
- data/lib/y_support/typing/enumerable.rb +1 -1
- data/lib/y_support/typing/hash/typing.rb +47 -29
- data/lib/y_support/typing/hash.rb +1 -1
- data/lib/y_support/typing/module/typing.rb +4 -6
- data/lib/y_support/typing/module.rb +1 -1
- data/lib/y_support/typing/object/typing.rb +64 -61
- data/lib/y_support/typing/object.rb +1 -1
- data/lib/y_support/typing.rb +4 -26
- data/lib/y_support/unicode.rb +5 -7
- data/lib/y_support/version.rb +1 -1
- data/lib/y_support/x.rb +11 -8
- data/lib/y_support.rb +2 -2
- data/test/abstract_algebra_test.rb +44 -55
- data/test/inert_recorder_test.rb +13 -18
- data/test/local_object_test.rb +13 -18
- data/test/misc_test.rb +15 -10
- data/test/name_magic_test.rb +1 -1
- data/test/null_object_test.rb +19 -26
- data/test/respond_to_test.rb +15 -16
- data/test/typing_test.rb +100 -103
- data/test/x_test.rb +16 -19
- data/y_support.gemspec +21 -17
- metadata +37 -8
- data/LICENSE +0 -22
@@ -1,8 +1,8 @@
|
|
1
|
-
#encoding: utf-8
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'y_support'
|
4
4
|
|
5
|
-
# Null object pattern implementation in YSupport
|
5
|
+
# Null object pattern implementation in +YSupport+. apart from the expected null
|
6
6
|
# object behavior (such as returning self in response to almost all messages),
|
7
7
|
# this null object instances can carry a signature specified by the user upon
|
8
8
|
# creation, which can serve to hint the origin of the null object. (This
|
@@ -17,7 +17,7 @@ class NullObject
|
|
17
17
|
@null_object_signature = null_object_signature
|
18
18
|
end
|
19
19
|
|
20
|
-
# Inquirer whether an object is a NullObject
|
20
|
+
# Inquirer whether an object is a +NullObject+. Again, optional signature
|
21
21
|
# argument can be given to distinguish between different null objects.
|
22
22
|
#
|
23
23
|
def null_object? signature=nil
|
@@ -60,7 +60,7 @@ class NullObject
|
|
60
60
|
#
|
61
61
|
def blank?; true end
|
62
62
|
|
63
|
-
# True if and only if the other object is a NullObject with same signature.
|
63
|
+
# True if and only if the other object is a +NullObject+ with same signature.
|
64
64
|
#
|
65
65
|
def == other
|
66
66
|
other.is_a?( self.class ) &&
|
@@ -78,13 +78,13 @@ end # class nullobject
|
|
78
78
|
|
79
79
|
|
80
80
|
class Object
|
81
|
-
# Always false for ordinary objects, overriden in NullObject instances.
|
81
|
+
# Always false for ordinary objects, overriden in +NullObject+ instances.
|
82
82
|
#
|
83
83
|
def null_object? signature=nil; false end
|
84
84
|
alias :null? :null_object?
|
85
85
|
|
86
|
-
# Converts
|
87
|
-
# specifies the signature of the null object to be created.
|
86
|
+
# Converts +#nil?+-positive objects to a +NullObject+. Second optional
|
87
|
+
# argument specifies the signature of the null object to be created.
|
88
88
|
#
|
89
89
|
def Maybe object, null_object_signature=nil
|
90
90
|
object.nil? ? NullObject.new( null_object_signature ) : object
|
@@ -94,3 +94,4 @@ class Object
|
|
94
94
|
#
|
95
95
|
def Null( signature=nil ); NullObject.new signature end
|
96
96
|
end
|
97
|
+
|
data/lib/y_support/respond_to.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'y_support'
|
2
|
-
require '
|
1
|
+
require 'y_support' unless defined? YSupport
|
2
|
+
require File.dirname( __FILE__ ) + '/matrix/misc'
|
data/lib/y_support/stdlib_ext.rb
CHANGED
data/lib/y_support/try.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
#encoding: utf-8
|
2
1
|
class Array
|
3
|
-
#
|
2
|
+
# Runtime assertions for Array.
|
4
3
|
|
5
4
|
# This method takes a block and fails with TypeError, if the receiver array
|
6
5
|
# fails to include the specified element. An optional argument customizes the
|
7
6
|
# error message (element description).
|
8
7
|
#
|
9
|
-
def
|
8
|
+
def aT_include element, what_is_self="array", what_is_element=nil
|
10
9
|
m = "%s is absent from #{what_is_self}!" %
|
11
10
|
if what_is_element then what_is_element.to_s.capitalize else
|
12
11
|
"Element (#{element.class} instance)"
|
13
12
|
end
|
14
13
|
tap { include? element or fail TypeError, m }
|
15
14
|
end
|
16
|
-
alias :aT_include :aT_includes
|
17
15
|
|
18
16
|
# Fails with TypeError if the array contains duplicates (using +#uniq+).
|
19
17
|
#
|
@@ -21,4 +19,47 @@ class Array
|
|
21
19
|
m = "#{what_is_self.to_s.capitalize} non-uniq!"
|
22
20
|
tap { self == uniq or fail TypeError, m }
|
23
21
|
end
|
22
|
+
|
23
|
+
# Fails with TypeError unless the receiver's +#empty?+ returns _true_.
|
24
|
+
#
|
25
|
+
def aT_empty what_is_receiver="array"
|
26
|
+
tap { empty? or fail TypeError, "%s not empty".X!( what_is_receiver ) }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Fails with TypeError unless the receiver's +#empty?+ returns _false_.
|
30
|
+
#
|
31
|
+
def aT_not_empty what_is_receiver="array"
|
32
|
+
tap { empty? and fail TypeError, "%s empty".X!( what_is_receiver ) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method takes a block and fails with +ArgumentError+ if the receiver
|
36
|
+
# array fails to include the specified element. An optional argument
|
37
|
+
# customizes the error message (element description).
|
38
|
+
#
|
39
|
+
def aA_include element, what_is_self="array", what_is_element=nil
|
40
|
+
m = "%s is absent from #{what_is_self}!" %
|
41
|
+
if what_is_element then what_is_element.to_s.capitalize else
|
42
|
+
"Element (#{element.class} instance)"
|
43
|
+
end
|
44
|
+
tap { include? element or fail ArgumentError, m }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Fails with ArgumentError if the array contains duplicates (using +#uniq+).
|
48
|
+
#
|
49
|
+
def aA_uniq what_is_self="array"
|
50
|
+
m = "#{what_is_self.to_s.capitalize} non-uniq!"
|
51
|
+
tap { self == uniq or fail ArgumentError, m }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Fails with ArgumentError unless the receiver's +#empty?+ returns _true_.
|
55
|
+
#
|
56
|
+
def aA_empty what_is_receiver="array"
|
57
|
+
tap { empty? or fail ArgumentError, "%s not empty".X!( what_is_receiver ) }
|
58
|
+
end
|
59
|
+
|
60
|
+
# Fails with ArgumentError unless the receiver's +#empty?+ returns _false_.
|
61
|
+
#
|
62
|
+
def aA_not_empty what_is_receiver="array"
|
63
|
+
tap { empty? and fail ArgumentError, "%s empty".X!( what_is_receiver ) }
|
64
|
+
end
|
24
65
|
end
|
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require File.dirname( __FILE__ ) + '/array/typing'
|
@@ -1,66 +1,64 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
1
|
module Enumerable
|
4
|
-
# Fails with TypeError unless all the members of the collection comply with
|
5
|
-
# the supplied block criterion. Optional arguments customize the error
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
2
|
+
# Fails with +TypeError+ unless all the members of the collection comply with
|
3
|
+
# the supplied block criterion. Optional arguments customize the error message.
|
4
|
+
# First optional argument describes the collection element, the second one
|
5
|
+
# describes the tested duck type. If the criterion block takes at least one
|
6
|
+
# argument, the receiver elemnts are passed to it (+#all?+ method). If the
|
7
|
+
# criterion block takes no arguments (arity 0), it is gradually executed inside
|
8
|
+
# the elements (using +#instance_exec+). If no block is given, all members are
|
9
|
+
# required to be truey.
|
12
10
|
#
|
13
11
|
def aT_all what_is_collection_element=nil, how_comply=nil, &b
|
14
12
|
e = what_is_collection_element || "collection element"
|
15
13
|
if block_given?
|
16
14
|
m = "Each #{e} must %s!" %
|
17
|
-
( how_comply ? how_comply : "comply with the
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
( how_comply ? how_comply : "comply with the specification" )
|
16
|
+
fail TypeError, m unless ( b.arity == 0 ?
|
17
|
+
all? { |e| e.instance_exec( &b ) } :
|
18
|
+
all? { |e| b.( e ) } )
|
21
19
|
else
|
22
20
|
m = "No #{e} must be nil or false!"
|
23
|
-
|
21
|
+
fail TypeError, m unless all? { |e| e }
|
24
22
|
end
|
25
23
|
return self
|
26
24
|
end
|
27
25
|
|
28
|
-
# Fails with TypeError unless all collection members are
|
26
|
+
# Fails with +TypeError+ unless all collection members are +#kind_of?+ the
|
29
27
|
# class supplied as argument. Second optional argument (collection element
|
30
28
|
# description) customizes the error message.
|
31
29
|
#
|
32
30
|
def aT_all_kind_of klass, what_is_collection_element=nil
|
33
31
|
e = what_is_collection_element || "collection element"
|
34
32
|
m = "Each #{e} must be kind of #{klass}!"
|
35
|
-
|
33
|
+
fail TypeError, m unless all? { |e| e.kind_of? klass }
|
36
34
|
return self
|
37
35
|
end
|
38
36
|
|
39
|
-
# Fails with TypeError unless all collection members declare compliance with
|
40
|
-
#
|
41
|
-
#
|
37
|
+
# Fails with +TypeError+ unless all collection members declare compliance with
|
38
|
+
# the class supplied as an argument. Second optional argument (collection
|
39
|
+
# element description) customizes the error message.
|
42
40
|
#
|
43
41
|
def aT_all_comply klass, what_is_collection_element=nil
|
44
42
|
e = what_is_collection_element || "collection element"
|
45
43
|
m = "Each #{e} must declare compliance to #{klass}!"
|
46
|
-
|
44
|
+
fail TypeError, m unless all? { |e| e.class_complies? klass }
|
47
45
|
return self
|
48
46
|
end
|
49
47
|
|
50
|
-
# Fails with TypeError unless all the collection members declare compliance
|
51
|
-
# with Numeric
|
48
|
+
# Fails with +TypeError+ unless all the collection members declare compliance
|
49
|
+
# with +Numeric+. Second optional argument (collection element description)
|
52
50
|
# customizes the error message.
|
53
51
|
#
|
54
52
|
def aT_all_numeric what_is_collection_element=nil
|
55
53
|
e = what_is_collection_element || "collection element"
|
56
54
|
m = "Each #{e} must declare compliance with Numeric!"
|
57
|
-
|
55
|
+
fail TypeError, m unless all? { |e| e.class_complies? Numeric }
|
58
56
|
return self
|
59
57
|
end
|
60
58
|
|
61
|
-
# Fails with TypeError unless all the collection members are included
|
62
|
-
# collection supplied as argument. Second optional argument (collection
|
63
|
-
#
|
59
|
+
# Fails with +TypeError+ unless all the collection members are included in the
|
60
|
+
# collection supplied as argument. Second optional argument (collection element
|
61
|
+
# description) customizes the error message.
|
64
62
|
#
|
65
63
|
def aT_subset_of other_collection, what_is_receiver_collection=nil,
|
66
64
|
what_is_other_collection=nil
|
@@ -69,7 +67,7 @@ module Enumerable
|
|
69
67
|
oc = what_is_other_collection ? what_is_other_collection.to_s.capitalize :
|
70
68
|
"the specified collection"
|
71
69
|
m = "The #{rc} must be a subset of #{oc}"
|
72
|
-
|
70
|
+
fail TypeError, m unless all? { |e| other_collection.include? e }
|
73
71
|
return self
|
74
72
|
end
|
75
73
|
end
|
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require File.dirname( __FILE__ ) + '/enumerable/typing'
|
@@ -1,12 +1,10 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
1
|
class Hash
|
4
2
|
# Merges the synonymous hash keys into a single key - useful for argument
|
5
3
|
# validation. Returns nil if neither main key, nor synonyms are found.
|
6
4
|
# Returns false (no merging) if the main key was found, but no synonym keys.
|
7
5
|
# Returns true (yes merging) if any of the synonym keys is found and
|
8
6
|
# renamed/merged to the main key. Value collisions in synonym keys (detected
|
9
|
-
# by
|
7
|
+
# by +#==+) raise +ArgumentError+.
|
10
8
|
#
|
11
9
|
def merge_synonym_keys!( key, *synonyms )
|
12
10
|
synonyms.reduce has_key?( key ) ? false : nil do |acc, syn|
|
@@ -20,57 +18,77 @@ class Hash
|
|
20
18
|
delete syn
|
21
19
|
next true
|
22
20
|
else
|
23
|
-
raise
|
21
|
+
raise TypeError, "Value collision between #{key} and its synonym #{syn}!"
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# supplied as a named argument
|
31
|
-
# will be merged with the main key, modifying the hash.)
|
26
|
+
# Calls +#merge_synonym_keys!+ first, then returns the value under the
|
27
|
+
# specified key. The first argument is the main key, synonym keys may be
|
28
|
+
# supplied as a named argument +:syn!+. (Bang indicates that the synonym
|
29
|
+
# keys will be merged with the main key, thus modifying the hash.)
|
32
30
|
#
|
33
31
|
def may_have key, options={}
|
34
32
|
merge_synonym_keys!( key, *options[:syn!] ).nil?
|
35
33
|
return self[key]
|
36
34
|
end
|
37
35
|
|
38
|
-
# This method behaves
|
39
|
-
#
|
40
|
-
# the key or any synonym has been found.
|
36
|
+
# This method behaves like +#may_have+, but it returns _true_/_false_ value
|
37
|
+
# instead of the value under the specified key.
|
41
38
|
#
|
42
39
|
def has? key, options={}
|
43
|
-
!merge_synonym_keys!( key, *options[:syn!] ).nil?
|
40
|
+
! merge_synonym_keys!( key, *options[:syn!] ).nil?
|
44
41
|
end
|
45
|
-
|
46
|
-
# This
|
42
|
+
|
43
|
+
# This runtime assertion raises +TypeError+ when:
|
47
44
|
# 1. Neither the required key nor any of its synonyms are present.
|
48
45
|
# 2. The supplied criterion block, if any, returns false when applied
|
49
46
|
# to the value of the key in question. If the block takes an argument
|
50
47
|
# (or more arguments), the value is passed in. If the block takes no
|
51
48
|
# arguments (arity 0), it is executed inside the singleton class of the
|
52
|
-
# receiver (using
|
49
|
+
# receiver (using +#instance_exec+ method).
|
53
50
|
#
|
54
51
|
def aT_has key, options={}, &b
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
raise TErr, m unless ( b.arity == 0 ? self[key].instance_exec( &b ) :
|
60
|
-
b.( self[key] ) )
|
52
|
+
fail TypeError, "Key '#{key}' absent!" unless has? key, options
|
53
|
+
self[key].tap do |val|
|
54
|
+
fail TypeError, "Value for #{key} of wrong type!" unless
|
55
|
+
( b.arity == 0 ? val.instance_exec( &b ) : b.( val ) ) if b
|
61
56
|
end
|
62
|
-
return self[key]
|
63
57
|
end
|
64
58
|
alias :must_have :aT_has
|
65
59
|
|
66
|
-
# This method behaves exactly like
|
67
|
-
#
|
60
|
+
# This method behaves exactly like +#aT_has+, but it raises +ArgumentError+
|
61
|
+
# instead of +TypeError+.
|
68
62
|
#
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
63
|
+
def aA_has key, options={}, &b
|
64
|
+
fail ArgumentError, "Key '#{key}' absent!" unless has? key, options
|
65
|
+
self[key].tap do |val|
|
66
|
+
fail ArgumentError, "Value for #{key} of wrong type!" unless
|
67
|
+
( b.arity == 0 ? val.instance_exec( &b ) : b.( val ) ) if b
|
74
68
|
end
|
75
69
|
end
|
70
|
+
|
71
|
+
# Fails with +TypeError+ unless the receiver's +#empty?+ returns _true_.
|
72
|
+
#
|
73
|
+
def aT_empty what_is_receiver="hash"
|
74
|
+
tap { empty? or fail TypeError, "%s not empty".X!( what_is_receiver ) }
|
75
|
+
end
|
76
|
+
|
77
|
+
# Fails with +TypeError+ unless the receiver's `#empty?` returns _false_.
|
78
|
+
#
|
79
|
+
def aT_not_empty what_is_receiver="hash"
|
80
|
+
tap { empty? and fail TypeError, "%s empty".X!( what_is_receiver ) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Fails with +ArgumentError+ unless the receiver's `#empty?` returns _true_.
|
84
|
+
#
|
85
|
+
def aA_empty what_is_receiver="hash"
|
86
|
+
tap { empty? or fail ArgumentError, "%s not empty".X!( what_is_receiver ) }
|
87
|
+
end
|
88
|
+
|
89
|
+
# Fails with +ArgumentError+ unless the receiver's `#empty?` returns _false_.
|
90
|
+
#
|
91
|
+
def aA_not_empty what_is_receiver="hash"
|
92
|
+
tap { empty? and fail ArgumentError, "%s empty".X!( what_is_receiver ) }
|
93
|
+
end
|
76
94
|
end
|
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require File.dirname( __FILE__ ) + '/hash/typing'
|
@@ -1,16 +1,13 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
1
|
class Module
|
4
2
|
# === Support for typing by declaration
|
5
3
|
|
6
4
|
# Compliance inquirer (declared compliance + ancestors).
|
7
5
|
#
|
8
6
|
def complies?( other_module )
|
9
|
-
other_module.aT_kind_of Module, "other module"
|
10
|
-
compliance.include? other_module
|
7
|
+
compliance.include? other_module.aT_kind_of( Module, "other module" )
|
11
8
|
end
|
12
9
|
|
13
|
-
# Declared
|
10
|
+
# Declared compliance inquirer.
|
14
11
|
#
|
15
12
|
def declares_compliance?( other_module )
|
16
13
|
other_module.aT_kind_of Module, "other module"
|
@@ -31,7 +28,8 @@ class Module
|
|
31
28
|
}.reduce( [], :+ ) ).uniq
|
32
29
|
end
|
33
30
|
|
34
|
-
#
|
31
|
+
# Using this method, the receiver explicitly declares that its interface
|
32
|
+
# complies with another module (class).
|
35
33
|
#
|
36
34
|
def declare_compliance! other_module
|
37
35
|
other_module.aT_kind_of Module, "other module"
|
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require File.dirname( __FILE__ ) + '/module/typing'
|
@@ -1,21 +1,19 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
1
|
require 'active_support/core_ext/object/blank'
|
4
|
-
require '
|
5
|
-
require '
|
2
|
+
require File.dirname( __FILE__ ) + '/../../core_ext/object/inspection'
|
3
|
+
require File.dirname( __FILE__ ) + '/../../core_ext/string/misc'
|
6
4
|
|
7
5
|
class Object
|
8
|
-
# ===
|
6
|
+
# === Typing by declaration
|
9
7
|
|
10
8
|
# Class compliance inquirer (declared compliance + class ancestors).
|
11
9
|
#
|
12
|
-
def class_complies?
|
10
|
+
def class_complies? klass
|
13
11
|
singleton_class_or_class.complies? klass
|
14
12
|
end
|
15
13
|
|
16
14
|
# Declared class compliance.
|
17
15
|
#
|
18
|
-
def class_declares_compliance?
|
16
|
+
def class_declares_compliance? klass
|
19
17
|
singleton_class_or_class.declares_compliance? klass
|
20
18
|
end
|
21
19
|
|
@@ -33,31 +31,29 @@ class Object
|
|
33
31
|
|
34
32
|
# Declaration of class compliance.
|
35
33
|
#
|
36
|
-
def declare_class_compliance!
|
34
|
+
def declare_class_compliance! klass
|
37
35
|
singleton_class_or_class.declare_compliance! klass
|
38
36
|
end
|
39
37
|
|
40
|
-
# ===
|
38
|
+
# === Runtime assertions
|
41
39
|
|
42
|
-
# This method takes a block and fails with TypeError
|
40
|
+
# This method takes a block and fails with +TypeError+, unless the receiver
|
43
41
|
# fullfills the block criterion. Optional arguments customize customize
|
44
42
|
# the error message. First optional argument describes the receiver, the
|
45
43
|
# second one describes the tested duck type. If the criterion block takes
|
46
44
|
# at least one argument, the receiver is passed to it. If the criterion block
|
47
45
|
# takes no arguments (arity 0), it is executed inside the singleton class of
|
48
|
-
# the receiver (using
|
46
|
+
# the receiver (using +#instance_exec+ method). If no block is given, it is
|
49
47
|
# checked, whether the object is truey.
|
50
48
|
#
|
51
49
|
def aT what_is_receiver=insp, how_comply=nil, &b
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# This method takes a block and fails with TypeError, unless the receiver
|
50
|
+
return tap { fail TypeError unless self } unless b
|
51
|
+
return self if b.( self )
|
52
|
+
m = "%s fails " + ( how_comply ? "to #{how_comply}" : "its check" )
|
53
|
+
fail TypeError, m.X!( what_is_receiver )
|
54
|
+
end
|
55
|
+
|
56
|
+
# This method takes a block and fails with +TypeError+, unless the receiver
|
61
57
|
# causes the supplied block <em>to return falsey value</em>. Optional arguments
|
62
58
|
# customize customize the error message. First optional argument describes the
|
63
59
|
# receiver, the second one describes the tested duck type. If the criterion
|
@@ -67,84 +63,91 @@ class Object
|
|
67
63
|
# no block is given, it is checked, whether the object is falsey.
|
68
64
|
#
|
69
65
|
def aT_not what_is_receiver=insp, how_comply=nil, &b
|
70
|
-
tap
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
fail TypeError, m.X!( what_is_receiver )
|
75
|
-
end
|
76
|
-
else fail TypeError if self end
|
77
|
-
end
|
66
|
+
return tap { fail TypeError if self } unless b
|
67
|
+
return self unless b.( self )
|
68
|
+
m = how_comply ? "%s must not #{how_comply}" : "%s fails its check"
|
69
|
+
fail TypeError, m.X!( what_is_receiver )
|
78
70
|
end
|
79
71
|
|
80
|
-
# Fails with TypeError unless the receiver is of the prescribed class. Second
|
72
|
+
# Fails with +TypeError+ unless the receiver is of the prescribed class. Second
|
81
73
|
# optional argument customizes the error message (receiver description).
|
82
74
|
#
|
83
75
|
def aT_kind_of klass, what_is_receiver=insp
|
84
|
-
|
85
|
-
|
86
|
-
end
|
76
|
+
return self if is_a? klass
|
77
|
+
fail TypeError, "%s not a #{klass}".X!( what_is_receiver )
|
87
78
|
end
|
88
79
|
alias aT_is_a aT_kind_of
|
89
80
|
|
90
|
-
# Fails with TypeError unless the receiver declares compliance with the
|
81
|
+
# Fails with +TypeError+ unless the receiver declares compliance with the
|
91
82
|
# given class, or is a descendant of that class. Second optional argument
|
92
83
|
# customizes the error message (receiver description).
|
93
84
|
#
|
94
|
-
def
|
95
|
-
if class_complies? klass
|
96
|
-
|
97
|
-
else self end
|
85
|
+
def aT_complies klass, what_is_receiver=insp
|
86
|
+
return self if class_complies? klass
|
87
|
+
fail TypeError, "%s does not comply with #{klass}".X!( what_is_receiver )
|
98
88
|
end
|
99
|
-
|
100
|
-
|
101
|
-
#
|
102
|
-
# description).
|
89
|
+
alias aT_class_complies aT_complies
|
90
|
+
|
91
|
+
# Fails with +TypeError+ unless the receiver responds to the given method.
|
92
|
+
# Second optional argument customizes the error message (receiver description).
|
103
93
|
#
|
104
94
|
def aT_respond_to method_name, what_is_receiver=insp
|
105
|
-
if respond_to? method_name
|
106
|
-
|
107
|
-
|
108
|
-
end
|
95
|
+
return self if respond_to? method_name
|
96
|
+
fail TypeError,
|
97
|
+
"%s does not respond to '#{method_name}'".X!( what_is_receiver )
|
109
98
|
end
|
110
99
|
alias aT_responds_to aT_respond_to
|
111
|
-
|
112
|
-
# Fails with TypeError unless the receiver, according to
|
100
|
+
|
101
|
+
# Fails with +TypeError+ unless the receiver, according to +#==+ method, is
|
113
102
|
# equal to the argument. Two more optional arguments customize the error
|
114
103
|
# message (receiver description and the description of the other object).
|
115
104
|
#
|
116
105
|
def aT_equal other, what_is_receiver=insp, what_is_other=nil
|
117
|
-
if self == other
|
118
|
-
|
119
|
-
|
120
|
-
end
|
106
|
+
return self if self == other
|
107
|
+
wo = what_is_other || "the prescribed value (#{other.insp})"
|
108
|
+
fail TypeError, "%s must be equal to %s".X!( [ what_is_receiver, wo ] )
|
121
109
|
end
|
122
110
|
|
123
|
-
# Fails with TypeError unless the receiver, according to
|
124
|
-
# from to the argument. Two more optional arguments customize the error
|
111
|
+
# Fails with +TypeError+ unless the receiver, according to +#==+ method,
|
112
|
+
# differs from to the argument. Two more optional arguments customize the error
|
125
113
|
# message (receiver description and the description of the other object).
|
126
114
|
#
|
127
115
|
def aT_not_equal other, what_is_receiver=insp, what_is_other=nil
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
else self end
|
116
|
+
return self unless self == other
|
117
|
+
wo = what_is_other || "the prescribed value (#{other.insp})"
|
118
|
+
fail TypeError, "%s must not == %s".X!( [ what_is_receiver, wo ] )
|
132
119
|
end
|
133
120
|
|
134
|
-
# Fails with TypeError unless
|
135
|
-
#
|
121
|
+
# Fails with +TypeError+ unless activesupport's +#blank+ returns true for
|
122
|
+
# the receiver.
|
136
123
|
#
|
137
124
|
def aT_blank what_is_receiver=insp
|
138
125
|
tap { blank? or fail TypeError, "%s not blank".X!( what_is_receiver ) }
|
139
126
|
end
|
140
127
|
|
141
|
-
# Fails with TypeError unless
|
142
|
-
#
|
128
|
+
# Fails with +TypeError+ unless activesupport's +#present+ returns true for
|
129
|
+
# the receiver.
|
143
130
|
#
|
144
131
|
def aT_present what_is_receiver=insp
|
145
132
|
tap { present? or fail TypeError, "%s not present".X!( what_is_receiver ) }
|
146
133
|
end
|
147
134
|
|
135
|
+
# Fails with +ArgumentError+ unless the +ActiveSupport+ method +#blank+ returns
|
136
|
+
# true for the receiver.
|
137
|
+
#
|
138
|
+
def aA_blank what_is_receiver=insp
|
139
|
+
tap { blank? or fail ArgumentError, "%s not blank".X!( what_is_receiver ) }
|
140
|
+
end
|
141
|
+
|
142
|
+
# Fails with +ArgumentError+ unless the +ActiveSupport+ method #present returns
|
143
|
+
# true for the receiver.
|
144
|
+
#
|
145
|
+
def aA_present what_is_receiver=insp
|
146
|
+
tap {
|
147
|
+
present? or fail ArgumentError, "%s not present".X!( what_is_receiver )
|
148
|
+
}
|
149
|
+
end
|
150
|
+
|
148
151
|
private
|
149
152
|
|
150
153
|
# Some objects do not have accessible singleton class. This method returns
|
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require File.dirname( __FILE__ ) + '/object/typing'
|