y_support 2.1.18 → 2.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/y_support/all.rb +2 -32
- data/lib/y_support/core_ext/array.rb +2 -2
- data/lib/y_support/core_ext/class.rb +2 -2
- data/lib/y_support/core_ext/enumerable.rb +2 -2
- data/lib/y_support/core_ext/hash/misc.rb +23 -10
- data/lib/y_support/core_ext/hash.rb +2 -2
- data/lib/y_support/core_ext/module/misc.rb +9 -0
- data/lib/y_support/core_ext/module.rb +2 -2
- data/lib/y_support/core_ext/numeric.rb +2 -2
- data/lib/y_support/core_ext/object/inspection.rb +8 -2
- data/lib/y_support/core_ext/object.rb +3 -3
- data/lib/y_support/core_ext/string/misc.rb +9 -12
- data/lib/y_support/core_ext/string.rb +2 -2
- data/lib/y_support/core_ext/symbol.rb +2 -2
- data/lib/y_support/core_ext.rb +1 -1
- data/lib/y_support/flex_coerce/class_methods.rb +49 -0
- data/lib/y_support/flex_coerce/flex_proxy.rb +121 -0
- data/lib/y_support/flex_coerce/module_methods.rb +37 -0
- data/lib/y_support/flex_coerce.rb +24 -0
- data/lib/y_support/kde.rb +1 -1
- data/lib/y_support/literate.rb +253 -0
- data/lib/y_support/local_object.rb +1 -1
- data/lib/y_support/name_magic/array_methods.rb +48 -0
- data/lib/y_support/name_magic/class_methods.rb +205 -161
- data/lib/y_support/name_magic/hash_methods.rb +33 -0
- data/lib/y_support/name_magic/namespace.rb +449 -0
- data/lib/y_support/name_magic.rb +358 -100
- data/lib/y_support/null_object.rb +1 -1
- data/lib/y_support/respond_to.rb +1 -1
- data/lib/y_support/stdlib_ext/matrix/misc.rb +2 -2
- data/lib/y_support/stdlib_ext/matrix.rb +2 -2
- data/lib/y_support/stdlib_ext.rb +1 -1
- data/lib/y_support/typing/array.rb +1 -1
- data/lib/y_support/typing/enumerable.rb +1 -1
- data/lib/y_support/typing/hash.rb +1 -1
- data/lib/y_support/typing/module.rb +1 -1
- data/lib/y_support/typing/object/typing.rb +17 -15
- data/lib/y_support/typing/object.rb +1 -1
- data/lib/y_support/typing.rb +14 -10
- data/lib/y_support/unicode.rb +1 -1
- data/lib/y_support/version.rb +1 -1
- data/lib/y_support/x.rb +2 -1
- data/test/flex_coerce_test.rb +134 -0
- data/test/literate_test.rb +231 -0
- data/test/misc_test.rb +49 -27
- data/test/name_magic_test.rb +907 -60
- data/test/typing_test.rb +7 -7
- metadata +14 -13
- data/lib/y_support/abstract_algebra.rb +0 -234
- data/lib/y_support/name_magic/array.rb +0 -38
- data/lib/y_support/name_magic/hash.rb +0 -31
- data/lib/y_support/name_magic/namespace_methods.rb +0 -260
- data/lib/y_support/try.rb +0 -133
- data/test/abstract_algebra_test.rb +0 -138
- data/test/performance_test_example.rb +0 -23
- data/test/try_test.rb +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ab593edcd28581e245478b60043c42f9440086c
|
4
|
+
data.tar.gz: 4fb00fe45dcb47047877141c63c8c4c5d24d5375
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a20065557690cf1b52ce7525f54342597ad97e071e13b2236ddc5584b5084ed7551d7c86a0b8ab9a9989bdcd266abc2e6cff929aa315d3cd2cab177230fc7dc
|
7
|
+
data.tar.gz: 81d28a6721cb01c0d181d6b17524cfa22674b86fdcdc6fed1658350713fbc5c5d672c604531eec70f08ef82322e28a6df4587487dfaa3ad5579ead28ce675dda
|
data/lib/y_support/all.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
|
3
3
|
require 'y_support'
|
4
|
+
require 'y_support/flex_coerce'
|
4
5
|
require 'y_support/name_magic'
|
5
6
|
require 'y_support/typing'
|
6
7
|
require 'y_support/unicode'
|
@@ -8,38 +9,7 @@ require 'y_support/respond_to'
|
|
8
9
|
require 'y_support/null_object'
|
9
10
|
require 'y_support/inert_recorder'
|
10
11
|
require 'y_support/local_object'
|
11
|
-
require 'y_support/
|
12
|
-
require 'y_support/abstract_algebra'
|
12
|
+
require 'y_support/literate'
|
13
13
|
require 'y_support/kde'
|
14
14
|
require 'y_support/x'
|
15
15
|
require 'y_support/misc'
|
16
|
-
|
17
|
-
|
18
|
-
# # Test me!
|
19
|
-
# class BlankSlate
|
20
|
-
# class << self
|
21
|
-
# # Hide the method named +name+ in the BlankSlate class. Don't
|
22
|
-
# # hide +instance_eval+ or any method beginning with "__".
|
23
|
-
# def hide( name )
|
24
|
-
# if instance_methods.include? name and
|
25
|
-
# name !~ /^(__|instance_eval)/
|
26
|
-
# @hidden_methods ||= {}
|
27
|
-
# @hidden_methods[name] = instance_method name
|
28
|
-
# undef_method name
|
29
|
-
# end
|
30
|
-
# end
|
31
|
-
|
32
|
-
# def find_hidden_method name
|
33
|
-
# @hidden_methods ||= {}
|
34
|
-
# @hidden_methods[name] || superclass.find_hidden_method( name )
|
35
|
-
# end
|
36
|
-
|
37
|
-
# # Redefine a previously hidden method
|
38
|
-
# def reveal name
|
39
|
-
# unbound_method = find_hidden_method name
|
40
|
-
# fail "Don't know how to reveal method '#{name}'" unless unbound_method
|
41
|
-
# define_method( name, unbound_method )
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
# end # class BlankSlate
|
45
|
-
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'array/misc'
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'class/misc'
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'enumerable/misc'
|
@@ -49,16 +49,26 @@ class Hash
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
#
|
53
|
-
# 2 arguments (key: value pair) and returns the new key.
|
52
|
+
# Like #with_keys, but modifies the receiver.
|
54
53
|
#
|
55
|
-
def
|
54
|
+
def with_keys!
|
55
|
+
keys.each_with_object self do |key, hsh|
|
56
|
+
hsh[ yield key ] = delete key
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# The difference from #with_keys is that modify_keys expects
|
61
|
+
# block that takes 2 arguments (key: value pair) and returns the
|
62
|
+
# new key.
|
63
|
+
#
|
64
|
+
def change_keys
|
56
65
|
each_with_object self.class.new do |pair, hsh|
|
57
66
|
hsh[ yield pair ] = self[ pair[0] ]
|
58
67
|
end
|
59
68
|
end
|
60
69
|
|
61
|
-
# Applies a block as a mapping on all values, returning a new
|
70
|
+
# Applies a block as a mapping on all values, returning a new
|
71
|
+
# hash.
|
62
72
|
#
|
63
73
|
def with_values
|
64
74
|
each_with_object self.class.new do |(k, v), hsh| hsh[ k ] = yield v end
|
@@ -70,8 +80,9 @@ class Hash
|
|
70
80
|
each_with_object self do |(k, v), hsh| hsh[ k ] = yield v end
|
71
81
|
end
|
72
82
|
|
73
|
-
# The difference from #
|
74
|
-
# that takes 2 arguments
|
83
|
+
# The difference from #with_values is that modify_values expects
|
84
|
+
# block that takes 2 arguments [ key, value ] and returns the
|
85
|
+
# new value.
|
75
86
|
#
|
76
87
|
def modify_values
|
77
88
|
each_with_object self.class.new do |pair, hsh|
|
@@ -96,15 +107,17 @@ class Hash
|
|
96
107
|
end
|
97
108
|
end
|
98
109
|
|
99
|
-
# Checking mainly against the collision with ActiveSupport's
|
110
|
+
# Checking mainly against the collision with ActiveSupport's
|
111
|
+
# Hash#slice.
|
100
112
|
if Hash.instance_methods.include? :slice then
|
101
113
|
warn "Collision: Method #slice already defined on Hash! (%s)" %
|
102
114
|
Hash.instance_method( :slice ).source_location
|
103
115
|
end
|
104
116
|
|
105
|
-
# A bit like Array#slice, but only takes 1 argument, which is
|
106
|
-
# or an Array, and returns the selection of the
|
107
|
-
# the range or are present in the
|
117
|
+
# A bit like Array#slice, but only takes 1 argument, which is
|
118
|
+
# either a Range, or an Array, and returns the selection of the
|
119
|
+
# hash for the keys that match the range or are present in the
|
120
|
+
# array.
|
108
121
|
#
|
109
122
|
def slice matcher
|
110
123
|
self.class[ case matcher
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'hash/misc'
|
@@ -1,4 +1,13 @@
|
|
1
1
|
class Module
|
2
|
+
# Hopefully not too ridiculous attempt to call a spade a spade. In the
|
3
|
+
# 1964 landmark paper "The mechanical evaluation of expressions", Peter
|
4
|
+
# Landin has defined an abstract language which is a basic for
|
5
|
+
# expression-oriented high-level languages popular today, such as Ruby.
|
6
|
+
# While Ruby's instance variables can be called "attributes", attribute
|
7
|
+
# readers seem to be called "selectors" in Landin's paper.
|
8
|
+
#
|
9
|
+
alias selector attr_reader
|
10
|
+
|
2
11
|
# Creates a module that inherits from the receiver and is parametrized
|
3
12
|
# with the given set of parameters. The parameters have form { symbol:
|
4
13
|
# value } and they cause singleton method(s) named "symbol" be defined
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'module/misc'
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'numeric/misc'
|
@@ -1,7 +1,13 @@
|
|
1
1
|
class Object
|
2
2
|
# Constructs the string "#{self.class}:#{self}". Useful for inspection.
|
3
3
|
#
|
4
|
-
def
|
5
|
-
|
4
|
+
def y_inspect( option=nil )
|
5
|
+
case option
|
6
|
+
when :full then "#<#{y_inspect}>"
|
7
|
+
when :short then
|
8
|
+
"#{self.class.name.to_s.split( "::" ).last}:#{self}"
|
9
|
+
else
|
10
|
+
"#{self.class}:#{self}"
|
11
|
+
end
|
6
12
|
end
|
7
13
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'object/misc'
|
3
|
+
require_relative 'object/inspection'
|
@@ -56,26 +56,23 @@ class String
|
|
56
56
|
gsub ' ', '_'
|
57
57
|
end
|
58
58
|
|
59
|
-
# Converts a string into a
|
60
|
-
# be created from any
|
61
|
-
#
|
62
|
-
#
|
63
|
-
# superfluous spaces, and underscores the remaining ones, before returning
|
64
|
-
# the string.
|
59
|
+
# Converts a string into a string suitable as a symbol. Although symbols can
|
60
|
+
# be created from any strings, sometimes it is good to have symbols without
|
61
|
+
# accented characters, punctuation and whitespaces. This method returns a
|
62
|
+
# string of these characteristics.
|
65
63
|
#
|
66
64
|
def standardize
|
67
|
-
ς = self.
|
65
|
+
ς = self.tr( "ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž",
|
66
|
+
"AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz"
|
67
|
+
)
|
68
68
|
",.;".each_char { |c| ς.gsub! c, " " }
|
69
|
-
ς.stripn
|
70
|
-
.squeeze(" ")
|
71
|
-
.underscore_spaces
|
69
|
+
ς.stripn.squeeze(" ").underscore_spaces
|
72
70
|
end
|
73
71
|
|
74
72
|
# Applies #standardize to the receiver and converts the result to a symbol.
|
75
73
|
#
|
76
74
|
def to_standardized_sym
|
77
|
-
standardize
|
78
|
-
.to_sym
|
75
|
+
standardize.to_sym
|
79
76
|
end
|
80
77
|
|
81
78
|
# Capitalizes a string and appends an exclamation mark. Also allows optional
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'string/misc'
|
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../../y_support'
|
2
|
+
require_relative 'symbol/misc'
|
data/lib/y_support/core_ext.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# This module defines class methods, with which the host class of FlexProxy
|
4
|
+
# is to be extended.
|
5
|
+
#
|
6
|
+
module FlexCoerce::ClassMethods
|
7
|
+
# Class method .coercion_table provides access to the table of coercion
|
8
|
+
# behavior specific to each host class. The table itself is a hash with
|
9
|
+
# method names as keys. Each value is an array of pairs [ type, block ],
|
10
|
+
# where type specifies the operand type, and block specifies the behavior
|
11
|
+
# when the method in question is invoked with the given operand type.
|
12
|
+
#
|
13
|
+
def coercion_table
|
14
|
+
@coercion_table ||= Hash.new { |hash, missing_key|
|
15
|
+
case missing_key
|
16
|
+
when Symbol then hash[ missing_key ] = []
|
17
|
+
else
|
18
|
+
hash[ missing_key.to_sym ]
|
19
|
+
end
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Class method .define_coercion allows the classes that use FlexCoerce to
|
24
|
+
# define custom coercion for certain symbols. The method expects: (1)
|
25
|
+
# object type (or a list of object types), (2) +:method+ parameter
|
26
|
+
# specifying the method(s) for which coercion is being defined, and (3) a
|
27
|
+
# block that defines the operation. The block should take 2 ordered
|
28
|
+
# arguments, representing first and second operand. The first operand is
|
29
|
+
# the object that invoked #coerce method, the second operand is an
|
30
|
+
# instance of the receiver class. Example:
|
31
|
+
#
|
32
|
+
# define_coercion Integer, method: :* do |operand1, operand2|
|
33
|
+
# operand2 * operand1 # swap the operands
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
def define_coercion *types,
|
37
|
+
method: fail( ArgumentError, "When defining coercion, " +
|
38
|
+
"method must be given!" ),
|
39
|
+
&block
|
40
|
+
unless block.arity == 2
|
41
|
+
fail ArgumentError, "The supplied block, which defines operation" +
|
42
|
+
"#{method}, must take exactly 2 arguments!"
|
43
|
+
end
|
44
|
+
# For each type, add one line to the coercion_table entry.
|
45
|
+
types.each do |type|
|
46
|
+
coercion_table[ method ] << [ type, block ]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# In FlexCoerce, #coerce method of the host class is made to return a pair
|
4
|
+
# [ proxy, receiver ], where proxy is an object of FlexProxy class. As name
|
5
|
+
# suggests, proxy represents and wraps argument that has been supplied to
|
6
|
+
# #coerce method. This gives the user the opportunity to teach the proxy to
|
7
|
+
# correctly respond to various operators (#+, #-, #*, #/,...) and other
|
8
|
+
# methods. Instances of FlexProxy are essentially a single-use objects –
|
9
|
+
# they respond to a single message, after which their life should end.
|
10
|
+
#
|
11
|
+
class FlexCoerce::FlexProxy
|
12
|
+
class << self
|
13
|
+
alias of new # allows statements such as FlexProxy.of( first_operand )
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :operand
|
17
|
+
|
18
|
+
# Method #host_class is delegated to self.class. It refers to the
|
19
|
+
# host class to which a parametrized subclass of FlexProxy belongs.
|
20
|
+
#
|
21
|
+
def host_class
|
22
|
+
self.class.host_class
|
23
|
+
end
|
24
|
+
|
25
|
+
# The constructor of FlexProxy requires only one parameter: The first operand
|
26
|
+
# which has been supplied to #coerce method.
|
27
|
+
#
|
28
|
+
def initialize first_operand
|
29
|
+
@operand = first_operand
|
30
|
+
end
|
31
|
+
|
32
|
+
# Proxy is essentially a single-use object. In its life, it receives a single
|
33
|
+
# message and returning the result. Unless the user specifically orders
|
34
|
+
# FlexProxy to respond to a method, it should raise TypeError.
|
35
|
+
#
|
36
|
+
def method_missing ß, arg
|
37
|
+
table_entry = host_class.coercion_table[ ß ]
|
38
|
+
response = table_entry.find { |type, closure| type === operand }
|
39
|
+
fail TypeError, "#{operand.class} not compatible with " +
|
40
|
+
"#{arg.class} and ##{ß} method!" unless response
|
41
|
+
response[ 1 ].call( operand, arg )
|
42
|
+
end
|
43
|
+
|
44
|
+
# Basic form of Proxy#+ method simply raises TypeError. The user is expected
|
45
|
+
# to override this method as necessary.
|
46
|
+
#
|
47
|
+
def + arg
|
48
|
+
table_entry = host_class.coercion_table[ :+ ]
|
49
|
+
response = table_entry.find { |type, closure| type === operand } or
|
50
|
+
fail TypeError, "#{arg.class} cannot be added to a #{operand.class}!"
|
51
|
+
response[ 1 ].call( operand, arg )
|
52
|
+
end
|
53
|
+
|
54
|
+
# Basic form of Proxy#- method simply raises TypeError. The user is expected
|
55
|
+
# to override this method as necessary.
|
56
|
+
#
|
57
|
+
def - arg
|
58
|
+
table_entry = host_class.coercion_table[ :- ]
|
59
|
+
response = table_entry.find { |type, closure| type === operand } or
|
60
|
+
fail TypeError, "#{arg.class} cannot be subtracted " +
|
61
|
+
"from a #{operand.class}!"
|
62
|
+
response[ 1 ].call( operand, arg )
|
63
|
+
end
|
64
|
+
|
65
|
+
# Basic form of Proxy#* method simply raises TypeError. The user is expected
|
66
|
+
# to override this method as necessary.
|
67
|
+
#
|
68
|
+
def * arg
|
69
|
+
table_entry = host_class.coercion_table[ :* ]
|
70
|
+
response = table_entry.find { |type, closure| type === operand } or
|
71
|
+
fail TypeError, "#{operand.class} cannot be multiplied " +
|
72
|
+
"by a #{arg.class}!"
|
73
|
+
response[ 1 ].call( operand, arg )
|
74
|
+
end
|
75
|
+
|
76
|
+
# Basic form of Proxy#/ method simply raises TypeError. The user is expected
|
77
|
+
# to override this method as necessary.
|
78
|
+
#
|
79
|
+
def / arg
|
80
|
+
table_entry = host_class.coercion_table[ :/ ]
|
81
|
+
response = table_entry.find { |type, closure| type === operand } or
|
82
|
+
fail TypeError, "#{arg.class} cannot be divided by a #{operand.class}!"
|
83
|
+
response[ 1 ].call( operand, arg )
|
84
|
+
end
|
85
|
+
|
86
|
+
# Basic form of Proxy#** method simply raises TypeError. The user is expected
|
87
|
+
# to override this method as necessary.
|
88
|
+
#
|
89
|
+
def ** arg
|
90
|
+
table_entry = host_class.coercion_table[ :** ]
|
91
|
+
response = table_entry.find { |type, closure| type === operand } or
|
92
|
+
fail TypeError, "#{arg.class} cannot be raised to a #{operand.class}!"
|
93
|
+
response[ 1 ].call( operand, arg )
|
94
|
+
end
|
95
|
+
|
96
|
+
# For less common operators, methods raising TypeError are defined below.
|
97
|
+
# Again, the user is expected to override them whenever necessary.
|
98
|
+
#
|
99
|
+
[ :%,
|
100
|
+
:div,
|
101
|
+
:divmod,
|
102
|
+
:fdiv,
|
103
|
+
:&,
|
104
|
+
:|,
|
105
|
+
:^,
|
106
|
+
:>,
|
107
|
+
:>=,
|
108
|
+
:<,
|
109
|
+
:<=,
|
110
|
+
:<=>,
|
111
|
+
:=== # Operator === is mostly too liberal to call coerce.
|
112
|
+
].each do |binary_operator|
|
113
|
+
define_method binary_operator do |arg|
|
114
|
+
table_entry = host_class.coercion_table[ binary_operator ]
|
115
|
+
response = table_entry.find { |type, closure| type === operand } or
|
116
|
+
fail TypeError, "#{arg.class} is not compatible with #{operand.class} " +
|
117
|
+
"and binary operator ##{binary_operator}"
|
118
|
+
response[ 1 ].call( operand, arg )
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end # class FlexCoerce::FlexProxy
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# This module contains methods with which FlexProxy and modules which include
|
4
|
+
# it are to be extended.
|
5
|
+
#
|
6
|
+
module FlexCoerce::ModuleMethods
|
7
|
+
# This method customizes the host class in which FlexCoerce is included
|
8
|
+
# by setting up a parametrized subclass of FlexCoerce::FlexProxy and
|
9
|
+
# extending the host class with FlexCoerce::ClassMethods.
|
10
|
+
#
|
11
|
+
def customize_class host_class
|
12
|
+
host_class.instance_exec do
|
13
|
+
# Set up a parametrized subclass of FlexCoerce::FlexProxy
|
14
|
+
param_class!( { FlexProxy: FlexCoerce::FlexProxy },
|
15
|
+
with: { host_class: host_class } )
|
16
|
+
end
|
17
|
+
host_class.extend FlexCoerce::ClassMethods
|
18
|
+
end
|
19
|
+
|
20
|
+
# This method customizes a module in which FlexCoerce is included by extending
|
21
|
+
# it with FlexCoerce::ModuleMethods.
|
22
|
+
#
|
23
|
+
def customize_module host_module
|
24
|
+
host_module.extend FlexCoerce::ModuleMethods
|
25
|
+
end
|
26
|
+
|
27
|
+
# Hook method which is invoked whenever a module is included in another module
|
28
|
+
# (or class, which is also a module).
|
29
|
+
#
|
30
|
+
def included receiver
|
31
|
+
if receiver.is_a? Class then # we have reached the host class
|
32
|
+
customize_class( receiver )
|
33
|
+
else # receiver is a Module
|
34
|
+
customize_module( receiver )
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'core_ext/object'
|
4
|
+
|
5
|
+
module FlexCoerce
|
6
|
+
require_relative 'flex_coerce/flex_proxy'
|
7
|
+
require_relative 'flex_coerce/class_methods'
|
8
|
+
require_relative 'flex_coerce/module_methods'
|
9
|
+
|
10
|
+
extend FlexCoerce::ModuleMethods
|
11
|
+
|
12
|
+
# Method #FlexProxy is delegated to the host class, it returns the
|
13
|
+
# parametrized subclass of FlexCoerce::FlexProxy specific to the host class.
|
14
|
+
#
|
15
|
+
def FlexProxy
|
16
|
+
self.class.FlexProxy
|
17
|
+
end
|
18
|
+
|
19
|
+
# FlexCoerce provides coerce method that returns a proxy object and self.
|
20
|
+
#
|
21
|
+
def coerce first_operand
|
22
|
+
return FlexProxy().of( first_operand ), self
|
23
|
+
end
|
24
|
+
end
|