striuct 0.0.11.1 → 0.1.7
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.
- data/History.rdoc +128 -35
- data/Manifest.txt +21 -6
- data/README.ja.rdoc +142 -83
- data/README.rdoc +130 -73
- data/Rakefile +5 -3
- data/example/benchmarks.rb +56 -0
- data/{example.rb → example/example.rb} +81 -70
- data/example/see_trace.rb +28 -0
- data/lib/striuct/abstract.rb +74 -0
- data/lib/striuct/conditions.rb +228 -0
- data/lib/striuct/frame.rb +8 -0
- data/lib/striuct/subclassable/basic.rb +135 -0
- data/lib/striuct/{classutil.rb → subclassable/classutil.rb} +5 -5
- data/lib/striuct/subclassable/eigen/basic.rb +38 -0
- data/lib/striuct/subclassable/eigen/constructor.rb +58 -0
- data/lib/striuct/subclassable/eigen/frame.rb +39 -0
- data/lib/striuct/subclassable/eigen/handy.rb +92 -0
- data/lib/striuct/subclassable/eigen/inner.rb +224 -0
- data/lib/striuct/subclassable/eigen/macro.rb +108 -0
- data/lib/striuct/subclassable/eigen/safety.rb +56 -0
- data/lib/striuct/subclassable/frame.rb +33 -0
- data/lib/striuct/subclassable/handy.rb +57 -0
- data/lib/striuct/subclassable/hashlike.rb +133 -0
- data/lib/striuct/subclassable/inner.rb +108 -0
- data/lib/striuct/subclassable/safety.rb +72 -0
- data/lib/striuct/subclassable/yaml.rb +14 -0
- data/lib/striuct/version.rb +2 -2
- data/lib/striuct.rb +3 -2
- data/test/test_striuct.rb +649 -20
- metadata +55 -24
- data/lib/striuct/core.rb +0 -56
- data/lib/striuct/import.rb +0 -95
- data/lib/striuct/subclass.rb +0 -262
- data/lib/striuct/subclass_eigen.rb +0 -428
- data/test/test_helper_import.rb +0 -4
- data/test/test_striuct_import.rb +0 -42
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative 'subclassable/frame'
|
2
|
+
|
3
|
+
class Striuct; class << self
|
4
|
+
# @group Constructor
|
5
|
+
|
6
|
+
alias_method :new_instance, :new
|
7
|
+
private :new_instance
|
8
|
+
|
9
|
+
# @param [Symbol, String] *names
|
10
|
+
# @return [Class] - with Subclass, Subclass:Eigen
|
11
|
+
def new(*names, &block)
|
12
|
+
# warning for Ruby's Struct.new user
|
13
|
+
first = names.first
|
14
|
+
if first.instance_of?(String) and /\A[A-Z]/ =~ first
|
15
|
+
warn "no define constant #{first}"
|
16
|
+
end
|
17
|
+
|
18
|
+
Class.new self do
|
19
|
+
names.each do |name|
|
20
|
+
member name
|
21
|
+
end
|
22
|
+
|
23
|
+
class_eval(&block) if block_given?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @yieldreturn [Class] (see Striuct.new) - reject floating class
|
28
|
+
# @return [void]
|
29
|
+
def define(&block)
|
30
|
+
raise ArgumentError, 'must with block' unless block_given?
|
31
|
+
|
32
|
+
new(&block).tap do |subclass|
|
33
|
+
subclass.instance_eval do
|
34
|
+
raise 'not yet finished' if members.empty?
|
35
|
+
close
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @groupend
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
alias_method :original_inherited, :inherited
|
45
|
+
|
46
|
+
def inherited(subclass)
|
47
|
+
attributes = (
|
48
|
+
if equal? ::Striuct
|
49
|
+
[[], {}, {}, {}, {}, {}, :prevent]
|
50
|
+
else
|
51
|
+
[*[@names, @conditions, @flavors, @defaults,\
|
52
|
+
@inferences, @aliases].map(&:dup), @protect_level]
|
53
|
+
end
|
54
|
+
)
|
55
|
+
|
56
|
+
eigen = self
|
57
|
+
|
58
|
+
subclass.class_eval do
|
59
|
+
original_inherited subclass
|
60
|
+
include Subclassable if ::Striuct.equal? eigen
|
61
|
+
|
62
|
+
@names, @conditions, @flavors, @defaults,\
|
63
|
+
@inferences, @aliases, @protect_level = *attributes
|
64
|
+
|
65
|
+
singleton_class.instance_eval do
|
66
|
+
define_method :initialize_copy do |original|
|
67
|
+
@names, @flavors, @defaults, @aliases =
|
68
|
+
*[@names, @flavors, @defaults, @aliases].map(&:dup)
|
69
|
+
@conditions, @inferences = @conditions.dup, @inferences.dup
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end; end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
class Striuct
|
2
|
+
|
3
|
+
# Useful Condition Patterns
|
4
|
+
module Conditions
|
5
|
+
module_function
|
6
|
+
|
7
|
+
# @param [Object] condition
|
8
|
+
def conditionable?(condition)
|
9
|
+
case condition
|
10
|
+
when Proc, Method
|
11
|
+
condition.arity == 1
|
12
|
+
else
|
13
|
+
condition.respond_to? :===
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param [Object] value
|
18
|
+
# @param [Proc, Method, #===] condition
|
19
|
+
# @param [self(class)] context
|
20
|
+
def pass?(value, condition, context)
|
21
|
+
if context && ! context.instance_of?(self)
|
22
|
+
raise ArgumentError,
|
23
|
+
"to change context is allowed in instance of #{self}"
|
24
|
+
end
|
25
|
+
|
26
|
+
case condition
|
27
|
+
when Proc
|
28
|
+
if context
|
29
|
+
context.instance_exec value, &condition
|
30
|
+
else
|
31
|
+
condition.call value
|
32
|
+
end
|
33
|
+
when Method
|
34
|
+
condition.call value
|
35
|
+
else
|
36
|
+
condition === value
|
37
|
+
end ? true : false
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [lambda]
|
41
|
+
def NOT(condition)
|
42
|
+
unless conditionable? condition
|
43
|
+
raise TypeError, 'wrong object for condition'
|
44
|
+
end
|
45
|
+
|
46
|
+
->v{! self.class.__send__(:pass?, v, condition, self)}
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [lambda]
|
50
|
+
def _logical_operator(delegated, *conditions)
|
51
|
+
unless conditions.all?{|c|conditionable? c}
|
52
|
+
raise TypeError, 'wrong object for condition'
|
53
|
+
end
|
54
|
+
|
55
|
+
->v{
|
56
|
+
conditions.__send__(delegated) {|condition|
|
57
|
+
self.class.__send__(:pass?, v, condition, self)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [lambda] check "match all conditions"
|
63
|
+
def AND(cond1, cond2, *conds)
|
64
|
+
_logical_operator :all?, cond1, cond2, *conds
|
65
|
+
end
|
66
|
+
|
67
|
+
alias_method :ALL, :AND
|
68
|
+
module_function :ALL
|
69
|
+
|
70
|
+
# @return [lambda]
|
71
|
+
def NAND(cond1, cond2, *conds)
|
72
|
+
! AND(cond1, cond2, *conds)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [lambda] check "match any condition"
|
76
|
+
def OR(cond1, cond2, *conds)
|
77
|
+
_logical_operator :any?, cond1, cond2, *conds
|
78
|
+
end
|
79
|
+
|
80
|
+
alias_method :ANY, :OR
|
81
|
+
module_function :ANY
|
82
|
+
|
83
|
+
# @return [lambda]
|
84
|
+
def NOR(cond1, cond2, *conds)
|
85
|
+
! OR(cond1, cond2, *conds)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [lambda]
|
89
|
+
def XOR(cond1, cond2, *conds)
|
90
|
+
_logical_operator :one?, cond1, cond2, *conds
|
91
|
+
end
|
92
|
+
|
93
|
+
alias_method :ONE, :XOR
|
94
|
+
module_function :ONE
|
95
|
+
|
96
|
+
# @return [lambda]
|
97
|
+
def XNOR(cond1, cond2, *conds)
|
98
|
+
! XOR(cond1, cond2, *conds)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [lambda] use #==
|
102
|
+
def EQUAL(obj)
|
103
|
+
->v{obj == v}
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [lambda] use #equal?
|
107
|
+
def SAME(obj)
|
108
|
+
->v{obj.equal? v}
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [lambda] true when respond to all method names
|
112
|
+
def RESPONSIBLE(name1, *names)
|
113
|
+
names = [name1, *names]
|
114
|
+
unless names.all?{|s|[Symbol, String].any?{|klass|s.kind_of? klass}}
|
115
|
+
raise TypeError, 'only Symbol or String for name'
|
116
|
+
end
|
117
|
+
|
118
|
+
->v{
|
119
|
+
names.all?{|name|v.respond_to? name}
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
alias_method :CAN, :RESPONSIBLE
|
124
|
+
alias_method :RESPOND_TO, :RESPONSIBLE
|
125
|
+
alias_method :responsible, :RESPONSIBLE
|
126
|
+
module_function :CAN, :responsible, :RESPOND_TO
|
127
|
+
|
128
|
+
# @return [lambda] true when faced no exceptions in checking all conditions
|
129
|
+
def NO_RAISES(condition1, *conditions)
|
130
|
+
conditions = [condition1, *conditions]
|
131
|
+
unless conditions.all?{|c|conditionable? c}
|
132
|
+
raise TypeError, 'wrong object for condition'
|
133
|
+
end
|
134
|
+
|
135
|
+
->v{
|
136
|
+
conditions.all?{|condition|
|
137
|
+
begin
|
138
|
+
self.class.__send__(:pass?, v, condition, self)
|
139
|
+
rescue Exception
|
140
|
+
false
|
141
|
+
else
|
142
|
+
true
|
143
|
+
end
|
144
|
+
}
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
alias_method :STILL, :NO_RAISES
|
149
|
+
module_function :STILL
|
150
|
+
|
151
|
+
# @return [lambda] true when catch the exception
|
152
|
+
def CATCH(exception=Exception, &condition)
|
153
|
+
raise ArgumentError unless conditionable? condition
|
154
|
+
raise TypeError unless exception.ancestors.include? Exception
|
155
|
+
|
156
|
+
->v{
|
157
|
+
begin
|
158
|
+
self.class.__send__(:pass?, v, condition, self)
|
159
|
+
rescue exception
|
160
|
+
true
|
161
|
+
rescue Exception
|
162
|
+
false
|
163
|
+
else
|
164
|
+
false
|
165
|
+
end
|
166
|
+
}
|
167
|
+
end
|
168
|
+
|
169
|
+
alias_method :RESCUE, :CATCH
|
170
|
+
module_function :RESCUE
|
171
|
+
|
172
|
+
# @return [lambda] check "all included objects match any conditions"
|
173
|
+
def GENERICS(condition1, *conditions)
|
174
|
+
conditions = [condition1, *conditions]
|
175
|
+
unless conditions.all?{|c|conditionable? c}
|
176
|
+
raise TypeError, 'wrong object for condition'
|
177
|
+
end
|
178
|
+
|
179
|
+
->list{
|
180
|
+
conditions.all?{|condition|
|
181
|
+
(list.respond_to?(:each_value) ? list.each_value : list.each).all?{|v|
|
182
|
+
self.class.__send__(:pass?, v, condition, self)
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
alias_method :generics, :GENERICS
|
189
|
+
module_function :generics
|
190
|
+
|
191
|
+
# @return [lambda]
|
192
|
+
def MEMBER_OF(list1, *lists)
|
193
|
+
lists = [list1, *lists]
|
194
|
+
unless lists.all?{|l|l.respond_to? :all?}
|
195
|
+
raise TypeError, 'list must respond #all?'
|
196
|
+
end
|
197
|
+
|
198
|
+
->v{
|
199
|
+
lists.all?{|list|list.include? v}
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
alias_method :member_of, :MEMBER_OF
|
204
|
+
module_function :member_of
|
205
|
+
|
206
|
+
BOOLEAN = OR(SAME(true), SAME(false))
|
207
|
+
|
208
|
+
# @return [BOOLEAN] "true or false"
|
209
|
+
def boolean
|
210
|
+
BOOLEAN
|
211
|
+
end
|
212
|
+
|
213
|
+
alias_method :bool, :boolean
|
214
|
+
module_function :bool
|
215
|
+
|
216
|
+
STRINGABLE = OR(String, Symbol, CAN(:to_str), CAN(:to_sym))
|
217
|
+
|
218
|
+
# @return [STRINGABLE] check "looks string family"
|
219
|
+
def stringable
|
220
|
+
STRINGABLE
|
221
|
+
end
|
222
|
+
|
223
|
+
class << self
|
224
|
+
private :_logical_operator
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
class Striuct; module Subclassable
|
2
|
+
# @group Basic
|
3
|
+
|
4
|
+
def initialize(*values)
|
5
|
+
@db, @locks = {}, {}
|
6
|
+
replace_values(*values)
|
7
|
+
end
|
8
|
+
|
9
|
+
# see self.class.*args
|
10
|
+
delegate_class_methods(
|
11
|
+
:members, :keys, :names,
|
12
|
+
:has_member?, :member?, :has_key?, :key?,
|
13
|
+
:length, :size
|
14
|
+
)
|
15
|
+
|
16
|
+
# @return [Boolean]
|
17
|
+
def ==(other)
|
18
|
+
__compare_all__ other, :==
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :===, :==
|
22
|
+
|
23
|
+
def eql?(other)
|
24
|
+
__compare_all__ other, :eql?
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Integer]
|
28
|
+
def hash
|
29
|
+
@db.hash
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [String]
|
33
|
+
def inspect
|
34
|
+
"#<#{self.class} (StrictStruct)".tap do |s|
|
35
|
+
each_pair do |name, value|
|
36
|
+
suffix = (has_default?(name) && default?(name)) ? '(default)' : nil
|
37
|
+
s << " #{name}=#{value.inspect}#{suffix}"
|
38
|
+
end
|
39
|
+
|
40
|
+
s << ">"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String]
|
45
|
+
def to_s
|
46
|
+
"#<struct #{self.class}".tap do |s|
|
47
|
+
each_pair do |name, value|
|
48
|
+
s << " #{name}=#{value.inspect}"
|
49
|
+
end
|
50
|
+
|
51
|
+
s << '>'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param [Symbol, String, Fixnum] key
|
56
|
+
def [](key)
|
57
|
+
__subscript__(key){|name|__get__ name}
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param [Symbol, String, Fixnum] key
|
61
|
+
# @param [Object] value
|
62
|
+
# @return [value]
|
63
|
+
def []=(key, value)
|
64
|
+
true_name = nil
|
65
|
+
__subscript__(key){|name|true_name = name; __set__ name, value}
|
66
|
+
rescue ConditionError
|
67
|
+
$@ = [
|
68
|
+
"#{$@[-1].sub(/[^:]+\z/){''}}in `[#{key}(#{true_name})]=': #{$!.message}",
|
69
|
+
$@[-1]
|
70
|
+
]
|
71
|
+
|
72
|
+
raise
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method :assign, :[]
|
76
|
+
|
77
|
+
# @yield [value]
|
78
|
+
# @yieldparam [Object] value - sequential under defined
|
79
|
+
# @see #each_name
|
80
|
+
# @yieldreturn [self]
|
81
|
+
# @return [Enumerator]
|
82
|
+
def each_value
|
83
|
+
return to_enum(__method__) unless block_given?
|
84
|
+
each_member{|member|yield self[member]}
|
85
|
+
end
|
86
|
+
|
87
|
+
alias_method :each, :each_value
|
88
|
+
|
89
|
+
# @yield [name, value]
|
90
|
+
# @yieldparam [Symbol] name
|
91
|
+
# @yieldparam [Object] value
|
92
|
+
# @yieldreturn [self]
|
93
|
+
# @return [Enumerator]
|
94
|
+
# @see #each_name
|
95
|
+
# @see #each_value
|
96
|
+
def each_pair
|
97
|
+
return to_enum(__method__) unless block_given?
|
98
|
+
each_name{|name|yield name, self[name]}
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Array]
|
102
|
+
def values
|
103
|
+
each_value.to_a
|
104
|
+
end
|
105
|
+
|
106
|
+
alias_method :to_a, :values
|
107
|
+
|
108
|
+
# @param [Fixnum, Range] *keys
|
109
|
+
# @return [Array]
|
110
|
+
def values_at(*keys)
|
111
|
+
[].tap {|r|
|
112
|
+
keys.each do |key|
|
113
|
+
case key
|
114
|
+
when Fixnum
|
115
|
+
r << self[key]
|
116
|
+
when Range
|
117
|
+
key.each do |n|
|
118
|
+
raise TypeError unless n.instance_of? Fixnum
|
119
|
+
r << self[n]
|
120
|
+
end
|
121
|
+
else
|
122
|
+
raise TypeError
|
123
|
+
end
|
124
|
+
end
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [self]
|
129
|
+
def freeze
|
130
|
+
[@db, @locks].each(&:freeze)
|
131
|
+
super
|
132
|
+
end
|
133
|
+
|
134
|
+
# @endgroup
|
135
|
+
end; end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Striuct
|
1
|
+
class Striuct; module Subclassable
|
2
2
|
|
3
3
|
|
4
4
|
# @author Kenichi Kamiya
|
@@ -6,16 +6,16 @@ module ClassUtil
|
|
6
6
|
|
7
7
|
private
|
8
8
|
|
9
|
-
# @macro delegate_class_method
|
10
9
|
def delegate_class_method(name)
|
11
10
|
define_method name do |*args, &block|
|
12
11
|
self.class.__send__ name, *args, &block
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
|
-
# @macro delegate_class_methods
|
17
15
|
def delegate_class_methods(*names)
|
18
|
-
|
16
|
+
unless names.length >= 1
|
17
|
+
raise ArgumentError, 'wrong number of argument 0 for 1+'
|
18
|
+
end
|
19
19
|
|
20
20
|
names.each{|name|delegate_class_method name}
|
21
21
|
end
|
@@ -23,4 +23,4 @@ module ClassUtil
|
|
23
23
|
end
|
24
24
|
|
25
25
|
|
26
|
-
end
|
26
|
+
end; end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Striuct; module Subclassable; module Eigen
|
2
|
+
# @group Basic
|
3
|
+
|
4
|
+
# @return [Array<Symbol>]
|
5
|
+
def names
|
6
|
+
@names.dup
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method :members, :names
|
10
|
+
alias_method :keys, :names
|
11
|
+
|
12
|
+
def has_member?(name)
|
13
|
+
originalkey_for(keyable_for name)
|
14
|
+
rescue Exception
|
15
|
+
false
|
16
|
+
else
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :member?, :has_member?
|
21
|
+
alias_method :has_key?, :has_member?
|
22
|
+
alias_method :key?, :has_key?
|
23
|
+
|
24
|
+
# @return [Integer]
|
25
|
+
def length
|
26
|
+
@names.length
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :size, :length
|
30
|
+
|
31
|
+
# @return [self]
|
32
|
+
def freeze
|
33
|
+
__stores__.each(&:freeze)
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
# @endgroup
|
38
|
+
end; end; end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Striuct; module Subclassable; module Eigen
|
2
|
+
# @group Constructor
|
3
|
+
|
4
|
+
# @return [Subclass]
|
5
|
+
def load_values(*values)
|
6
|
+
new_instance(*values)
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method :new, :load_values
|
10
|
+
|
11
|
+
# @param [#each_pair, #keys] pairs ex: Hash, Struct
|
12
|
+
# @return [Subclass]
|
13
|
+
def load_pairs(pairs)
|
14
|
+
unless pairs.respond_to?(:each_pair) and pairs.respond_to?(:keys)
|
15
|
+
raise TypeError, 'no pairs object'
|
16
|
+
end
|
17
|
+
|
18
|
+
raise ArgumentError, "different members" unless (pairs.keys - keys).empty?
|
19
|
+
|
20
|
+
new.tap {|instance|
|
21
|
+
pairs.each_pair do |name, value|
|
22
|
+
instance[name] = value
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method :[], :load_pairs
|
28
|
+
|
29
|
+
# @yieldparam [Subclass] instance
|
30
|
+
# @yieldreturn [Subclass] instance
|
31
|
+
# @return [void]
|
32
|
+
# for build the fixed object
|
33
|
+
def define(options={lock: true, strict: true})
|
34
|
+
raise TypeError, 'arguments have to be pairs object' unless options.respond_to? :keys
|
35
|
+
raise ArgumentError, 'Unknown parameters' unless (options.keys - [:lock, :strict]).empty?
|
36
|
+
raise ArgumentError, 'must with block' unless block_given?
|
37
|
+
|
38
|
+
lock, strict = options[:lock], options[:strict]
|
39
|
+
|
40
|
+
new.tap {|instance|
|
41
|
+
yield instance
|
42
|
+
|
43
|
+
unless (yets = each_name.select{|name|! instance.assign?(name)}).empty?
|
44
|
+
raise "not assigned members are, yet '#{yets.inspect} in #{self}'"
|
45
|
+
end
|
46
|
+
|
47
|
+
if strict &&
|
48
|
+
! (invalids = each_name.select{|name|! instance.valid?(name)}).empty?
|
49
|
+
|
50
|
+
raise ConditionError, "invalids members are, yet '#{invalids.inspect} in #{self}'"
|
51
|
+
end
|
52
|
+
|
53
|
+
instance.lock if lock
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
# @endgroup
|
58
|
+
end; end; end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../../conditions'
|
2
|
+
|
3
|
+
class Striuct; module Subclassable
|
4
|
+
|
5
|
+
# @author Kenichi Kamiya
|
6
|
+
module Eigen
|
7
|
+
include Conditions
|
8
|
+
|
9
|
+
NAMING_RISKS = {
|
10
|
+
conflict: 10,
|
11
|
+
no_identifier: 9,
|
12
|
+
bad_manners: 5,
|
13
|
+
no_ascii: 3,
|
14
|
+
strict: 0
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
PROTECT_LEVELS = {
|
18
|
+
struct: {error: 99, warn: 99},
|
19
|
+
warning: {error: 99, warn: 5},
|
20
|
+
error: {error: 9, warn: 5},
|
21
|
+
prevent: {error: 5, warn: 1},
|
22
|
+
nervous: {error: 1, warn: 1}
|
23
|
+
}.each(&:freeze).freeze
|
24
|
+
|
25
|
+
INFERENCE = Object.new.freeze
|
26
|
+
|
27
|
+
if respond_to? :private_constant
|
28
|
+
private_constant :INFERENCE
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end; end
|
33
|
+
|
34
|
+
require_relative 'basic'
|
35
|
+
require_relative 'constructor'
|
36
|
+
require_relative 'safety'
|
37
|
+
require_relative 'handy'
|
38
|
+
require_relative 'macro'
|
39
|
+
require_relative 'inner'
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class Striuct; module Subclassable; module Eigen
|
2
|
+
# @group Struct+ Handy
|
3
|
+
|
4
|
+
# @yield [name]
|
5
|
+
# @yieldparam [Symbol] name - sequential under defined
|
6
|
+
# @yieldreturn [self]
|
7
|
+
# @return [Enumerator]
|
8
|
+
def each_name(&block)
|
9
|
+
return to_enum(__method__) unless block_given?
|
10
|
+
_names.each(&block)
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :each_member, :each_name
|
15
|
+
alias_method :each_key, :each_name
|
16
|
+
|
17
|
+
# @yield [index]
|
18
|
+
# @yieldparam [Integer] Index
|
19
|
+
# @yieldreturn [self]
|
20
|
+
# @return [Enumerator]
|
21
|
+
def each_index(&block)
|
22
|
+
return to_enum(__method__) unless block_given?
|
23
|
+
_names.each_index(&block)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [Symbol, String] name
|
28
|
+
def original?(name)
|
29
|
+
if member? name
|
30
|
+
@names.include? name
|
31
|
+
else
|
32
|
+
raise NameError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param [Symbol, String] name
|
37
|
+
def aliased?(name)
|
38
|
+
if member? name
|
39
|
+
@aliases.has_key? name
|
40
|
+
else
|
41
|
+
raise NameError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [Symbol, String] original
|
46
|
+
def has_aliases?(original)
|
47
|
+
if original? original
|
48
|
+
@aliases.has_value? original
|
49
|
+
else
|
50
|
+
raise NameError
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param [Symbol, String] original
|
55
|
+
# @return [Array<Symbol>]
|
56
|
+
def aliases_for(original)
|
57
|
+
original = keyable_for original
|
58
|
+
|
59
|
+
if has_aliases? original
|
60
|
+
_aliases_for original
|
61
|
+
else
|
62
|
+
raise NameError
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param [Symbol, String] name
|
67
|
+
def has_flavor?(name)
|
68
|
+
name = originalkey_for(keyable_for name)
|
69
|
+
|
70
|
+
! flavor_for(name).nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param [Symbol, String] name
|
74
|
+
def has_default?(name)
|
75
|
+
name = originalkey_for(keyable_for name)
|
76
|
+
|
77
|
+
@defaults.has_key? name
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [Symbol, String] name
|
81
|
+
def default_for(name)
|
82
|
+
name = originalkey_for(keyable_for name)
|
83
|
+
|
84
|
+
if has_default? name
|
85
|
+
_default_for name
|
86
|
+
else
|
87
|
+
raise "#{name} has no default value"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# @endgroup
|
92
|
+
end; end; end
|