striuct 0.4.4 → 0.7.0
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 +7 -0
- data/MIT-LICENSE.txt +21 -0
- data/README.md +20 -41
- data/lib/striuct.rb +3 -3
- data/lib/striuct/classmethods/README.md +2 -2
- data/lib/striuct/classmethods/adjustment.rb +15 -13
- data/lib/striuct/classmethods/attributes.rb +93 -91
- data/lib/striuct/classmethods/conflict_management.rb +109 -106
- data/lib/striuct/classmethods/constructor.rb +47 -54
- data/lib/striuct/classmethods/copy.rb +45 -43
- data/lib/striuct/classmethods/default.rb +23 -21
- data/lib/striuct/classmethods/enum.rb +46 -44
- data/lib/striuct/classmethods/fix.rb +23 -21
- data/lib/striuct/classmethods/hashdeepdupulicatable.rb +14 -16
- data/lib/striuct/classmethods/inner.rb +57 -64
- data/lib/striuct/classmethods/length.rb +12 -10
- data/lib/striuct/classmethods/macro.rb +109 -111
- data/lib/striuct/classmethods/names.rb +69 -65
- data/lib/striuct/classmethods/predicate.rb +131 -138
- data/lib/striuct/classmethods/requirements.rb +3 -1
- data/lib/striuct/classmethods/to_struct.rb +21 -18
- data/lib/striuct/classmethods/validation.rb +15 -13
- data/lib/striuct/instancemethods/README.md +2 -2
- data/lib/striuct/instancemethods/assign.rb +29 -27
- data/lib/striuct/instancemethods/cast.rb +28 -26
- data/lib/striuct/instancemethods/compare.rb +26 -24
- data/lib/striuct/instancemethods/default.rb +31 -29
- data/lib/striuct/instancemethods/delegate_class_methods.rb +36 -32
- data/lib/striuct/instancemethods/enum.rb +86 -84
- data/lib/striuct/instancemethods/getter.rb +39 -37
- data/lib/striuct/instancemethods/hashy.rb +99 -97
- data/lib/striuct/instancemethods/keyvalidatable.rb +8 -6
- data/lib/striuct/instancemethods/lock.rb +46 -44
- data/lib/striuct/instancemethods/object.rb +50 -48
- data/lib/striuct/instancemethods/requirements.rb +11 -9
- data/lib/striuct/instancemethods/safety.rb +11 -9
- data/lib/striuct/instancemethods/setter.rb +46 -49
- data/lib/striuct/instancemethods/to_s.rb +39 -37
- data/lib/striuct/instancemethods/validation.rb +31 -29
- data/lib/striuct/instancemethods/values.rb +52 -33
- data/lib/striuct/requirements.rb +3 -1
- data/lib/striuct/singleton_class.rb +12 -17
- data/lib/striuct/structs.rb +3 -3
- metadata +48 -186
- data/.gitignore +0 -35
- data/.travis.yml +0 -20
- data/.yardopts +0 -1
- data/Gemfile +0 -11
- data/History.old(~0.3.n).rdoc +0 -289
- data/MIT-LICENSE +0 -22
- data/Rakefile +0 -10
- data/benchmark/basics.rb +0 -56
- data/example/README.rb +0 -53
- data/example/example1.rb +0 -235
- data/example/example2.rb +0 -22
- data/example/see_trace.rb +0 -32
- data/striuct.gemspec +0 -36
- data/test/helper.rb +0 -5
- data/test/test_sglc-constructor.rb +0 -36
- data/test/test_subc-c-add_members.rb +0 -13
- data/test/test_subc-c-close_member.rb +0 -36
- data/test/test_subc-c-constructor.rb +0 -92
- data/test/test_subc-c-copy.rb +0 -71
- data/test/test_subc-c-freeze.rb +0 -36
- data/test/test_subc-c-inheritable.rb +0 -58
- data/test/test_subc-c-safety_naming.rb +0 -73
- data/test/test_subc-f-alias_member.rb +0 -54
- data/test/test_subc-f-enum.rb +0 -139
- data/test/test_subc-f-predicate.rb +0 -711
- data/test/test_subc-f-to_struct.rb +0 -61
- data/test/test_subc-f-validation_util.rb +0 -59
- data/test/test_subc-f_debug.rb +0 -39
- data/test/test_subc-f_name.rb +0 -525
- data/test/test_subc-i-accessor.rb +0 -138
- data/test/test_subc-i-adjuster.rb +0 -95
- data/test/test_subc-i-assign.rb +0 -53
- data/test/test_subc-i-basic.rb +0 -32
- data/test/test_subc-i-cast.rb +0 -27
- data/test/test_subc-i-compare.rb +0 -52
- data/test/test_subc-i-copy.rb +0 -23
- data/test/test_subc-i-default_value.rb +0 -129
- data/test/test_subc-i-freeze.rb +0 -19
- data/test/test_subc-i-hashlike.rb +0 -144
- data/test/test_subc-i-keyvalidatable.rb +0 -25
- data/test/test_subc-i-lock.rb +0 -40
- data/test/test_subc-i-must.rb +0 -30
- data/test/test_subc-i-to_s_family.rb +0 -26
- data/test/test_subc-i-validation_inference.rb +0 -51
- data/test/test_subc-i-validation_specific_conditions.rb +0 -297
- data/test/test_subc-i-validation_with_getter.rb +0 -33
- data/test/test_version.rb +0 -13
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c59316edafe027980857f258404996caaee0be26a0ad3265acee3cb067477db6
|
4
|
+
data.tar.gz: '086afe2f12bb06050cd7964a774fd087e6a7a710f0d54fe6bb3c4e647490e2d7'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 86c436676285e90dbafd4e1f9293b5cccfda99ce060e07a38893f4f0979c4c9f0b7c1c41da63e10ee479ff1323fa0f585c92113929bce766b072e577dc95b8cb
|
7
|
+
data.tar.gz: 0fca1e67d31013254edeb00043cf42699a3845b83bd4979db8623d0ef2786daff07db0ced0dcda068f297e1d577fca063703592f65242c26d793a3e17e9fb786
|
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Kenichi Kamiya
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
striuct
|
2
2
|
=======
|
3
3
|
|
4
|
-
|
4
|
+

|
5
5
|
[](http://badge.fury.io/rb/striuct)
|
6
6
|
|
7
7
|
Description
|
@@ -25,7 +25,7 @@ Features
|
|
25
25
|
* Member aliasing
|
26
26
|
* Inheritable
|
27
27
|
* Handling between nil <-> unassigned
|
28
|
-
*
|
28
|
+
* Similar API for Hash
|
29
29
|
|
30
30
|
### Onepoint
|
31
31
|
|
@@ -35,17 +35,26 @@ Features
|
|
35
35
|
Usage
|
36
36
|
-----
|
37
37
|
|
38
|
+
Require Ruby 2.6 or later
|
39
|
+
|
40
|
+
Add this line to your `Gemfile`
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
gem 'striuct', '>= 0.7.0', '< 0.8.0'
|
44
|
+
```
|
45
|
+
|
38
46
|
### Overview - Case 1
|
39
47
|
|
40
48
|
```ruby
|
41
49
|
require 'striuct'
|
42
50
|
|
43
51
|
class Person < Striuct
|
44
|
-
member :
|
45
|
-
alias_member :name, :
|
52
|
+
member :full_name, AND(String, /\A.+\z/) # Flexible Validation
|
53
|
+
alias_member :name, :full_name # Use other name
|
46
54
|
end
|
47
55
|
|
48
|
-
|
56
|
+
# Inheritable
|
57
|
+
class User < Person
|
49
58
|
member :id, Integer, # Looks typed validation
|
50
59
|
default_proc: ->{User.next_id} # With default value
|
51
60
|
|
@@ -56,26 +65,26 @@ class User < Person # Inheritable
|
|
56
65
|
end
|
57
66
|
|
58
67
|
john = User.new 'john'
|
59
|
-
john[:name] #=> 'john'
|
68
|
+
john[:name] #=> 'john'
|
60
69
|
john.name = '' #=> Exception # Validate with setter
|
61
70
|
john.id #=> 1
|
62
71
|
ken = User[name: 'ken'] # Construct from hash
|
63
72
|
ken.id #=> 2
|
64
73
|
```
|
74
|
+
|
65
75
|
### Overview - Case 2
|
66
76
|
|
67
77
|
```ruby
|
68
78
|
class Foo < Striuct
|
69
79
|
member :foo
|
70
|
-
member :bar, Numeric
|
71
|
-
inference: true # And use inference Validation
|
80
|
+
member :bar, Numeric
|
72
81
|
member :with_adjuster, Integer,
|
73
82
|
&->v{Integer v} # Use adjuster before a setter
|
74
83
|
end
|
75
84
|
|
76
85
|
foo = Foo.new
|
77
86
|
|
78
|
-
# nil <->
|
87
|
+
# nil <-> unassigned
|
79
88
|
foo.foo #=> nil
|
80
89
|
foo.assigned?(:foo) #=> false
|
81
90
|
foo.foo = nil
|
@@ -85,7 +94,6 @@ foo.assigned?(:foo) #=> true
|
|
85
94
|
foo.lock(:foo)
|
86
95
|
foo.foo = nil #=> error
|
87
96
|
|
88
|
-
# Inference Validation
|
89
97
|
foo.bar = 1.2 #=> pass # memorize 1.2's class is Float
|
90
98
|
foo.bar = 1 #=> error # 1 is not Float
|
91
99
|
|
@@ -104,37 +112,8 @@ end
|
|
104
112
|
UseMustOption.new #=> InvalidOperationError "`foo` require a value under `must` option "
|
105
113
|
```
|
106
114
|
|
107
|
-
|
108
|
-
### How to build flexible conditions ?
|
109
|
-
|
110
|
-
* That from validation library.
|
111
|
-
See the [validation-API](http://kachick.github.com/validation/yard/frames.html)
|
112
|
-
|
113
|
-
Requirements
|
114
|
-
-------------
|
115
|
-
|
116
|
-
* Ruby - [1.9.2 or later](http://travis-ci.org/#!/kachick/striuct)
|
117
|
-
|
118
|
-
Install
|
119
|
-
-------
|
120
|
-
|
121
|
-
```bash
|
122
|
-
gem install striuct
|
123
|
-
```
|
124
|
-
|
125
115
|
Link
|
126
116
|
----
|
127
117
|
|
128
|
-
* [
|
129
|
-
* [
|
130
|
-
* [API](http://kachick.github.com/striuct/yard/frames.html)
|
131
|
-
* [issues](https://github.com/kachick/striuct/issues)
|
132
|
-
* [CI](http://travis-ci.org/#!/kachick/striuct)
|
133
|
-
* [gem](https://rubygems.org/gems/striuct)
|
134
|
-
|
135
|
-
License
|
136
|
-
--------
|
137
|
-
|
138
|
-
The MIT X11 License
|
139
|
-
Copyright (c) 2011 Kenichi Kamiya
|
140
|
-
See MIT-LICENSE for further details.
|
118
|
+
* [Repository](https://github.com/kachick/striuct)
|
119
|
+
* [API documents](https://kachick.github.io/striuct/)
|
data/lib/striuct.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# striuct - Struct++
|
2
4
|
# Copyright (c) 2011-2012 Kenichi Kamiya
|
3
5
|
|
4
6
|
# @abstract
|
5
7
|
class Striuct
|
6
|
-
|
7
8
|
class Error < StandardError; end
|
8
9
|
class InvalidOperationError < Error; end
|
9
|
-
|
10
10
|
end
|
11
11
|
|
12
|
-
require_relative 'striuct/requirements'
|
12
|
+
require_relative 'striuct/requirements'
|
@@ -1,15 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
def adjuster_for(key)
|
7
|
-
autonym = autonym_for_key key
|
8
|
-
raise KeyError unless with_adjuster? autonym
|
9
|
-
|
10
|
-
_attributes_for(autonym).adjuster
|
11
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Striuct
|
4
|
+
module ClassMethods
|
5
|
+
# @group Adjuster
|
12
6
|
|
13
|
-
|
7
|
+
# @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
|
8
|
+
def adjuster_for(key)
|
9
|
+
autonym = autonym_for_key(key)
|
10
|
+
raise KeyError unless with_adjuster?(autonym)
|
14
11
|
|
15
|
-
|
12
|
+
_attributes_for(autonym).adjuster
|
13
|
+
end
|
14
|
+
|
15
|
+
# @endgroup
|
16
|
+
end
|
17
|
+
end
|
@@ -1,114 +1,116 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
define_method :"with_#{role}?" do
|
23
|
-
@hash.has_key? role
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Striuct
|
4
|
+
module ClassMethods
|
5
|
+
# Attributes for autonym of each member
|
6
|
+
class Attributes
|
7
|
+
VALUES = [:condition,
|
8
|
+
:adjuster].freeze
|
9
|
+
|
10
|
+
BOOLEANS = [
|
11
|
+
:must,
|
12
|
+
:safety_setter,
|
13
|
+
:safety_getter
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@hash = {
|
18
|
+
must: false,
|
19
|
+
safety_setter: false,
|
20
|
+
safety_getter: false
|
21
|
+
}
|
24
22
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
|
24
|
+
VALUES.each do |role|
|
25
|
+
define_method :"with_#{role}?" do
|
26
|
+
@hash.key?(role)
|
27
|
+
end
|
28
|
+
|
29
|
+
define_method role do
|
30
|
+
@hash.fetch(role)
|
31
|
+
end
|
28
32
|
end
|
29
|
-
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
def condition=(condition)
|
35
|
+
unless ::Validation.conditionable?(condition)
|
36
|
+
raise TypeError, 'wrong object for condition'
|
37
|
+
end
|
38
|
+
|
39
|
+
@hash[:condition] = condition
|
34
40
|
end
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
def adjuster=(adjuster)
|
43
|
+
unless ::Validation.adjustable?(adjuster)
|
44
|
+
raise ArgumentError, 'wrong object for adjuster'
|
45
|
+
end
|
38
46
|
|
39
|
-
|
40
|
-
unless ::Validation.adjustable? adjuster
|
41
|
-
raise ArgumentError, 'wrong object for adjuster'
|
47
|
+
@hash[:adjuster] = adjuster
|
42
48
|
end
|
43
49
|
|
44
|
-
|
45
|
-
|
50
|
+
BOOLEANS.each do |role|
|
51
|
+
define_method :"with_#{role}?" do
|
52
|
+
@hash.fetch(role)
|
53
|
+
end
|
54
|
+
|
55
|
+
define_method :"#{role}=" do |arg|
|
56
|
+
raise TypeError unless arg.equal?(true) || arg.equal?(false)
|
46
57
|
|
47
|
-
|
48
|
-
|
49
|
-
@hash.fetch role
|
58
|
+
@hash[role] = arg
|
59
|
+
end
|
50
60
|
end
|
51
|
-
|
52
|
-
define_method :"#{role}=" do |arg|
|
53
|
-
raise TypeError unless arg.equal?(true) or arg.equal?(false)
|
54
61
|
|
55
|
-
|
56
|
-
|
57
|
-
|
62
|
+
def with_default?
|
63
|
+
@hash.key?(:default_value)
|
64
|
+
end
|
58
65
|
|
59
|
-
|
60
|
-
|
61
|
-
|
66
|
+
def default_value
|
67
|
+
@hash.fetch(:default_value)
|
68
|
+
end
|
62
69
|
|
63
|
-
|
64
|
-
|
65
|
-
|
70
|
+
def default_type
|
71
|
+
@hash.fetch(:default_type)
|
72
|
+
end
|
66
73
|
|
67
|
-
|
68
|
-
|
69
|
-
|
74
|
+
# @param [Symbol] type - :value / :lazy
|
75
|
+
def set_default(value, type)
|
76
|
+
raise TypeError unless type.equal?(:value) || type.equal?(:lazy)
|
70
77
|
|
71
|
-
|
72
|
-
def set_default(value, type)
|
73
|
-
raise TypeError unless type.equal?(:value) or type.equal?(:lazy)
|
74
|
-
check_default_lazy_proc value if type.equal?(:lazy)
|
75
|
-
|
76
|
-
@hash[:default_type] = type
|
77
|
-
@hash[:default_value] = value
|
78
|
-
end
|
78
|
+
check_default_lazy_proc(value) if type.equal?(:lazy)
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
arity = _proc.arity
|
83
|
-
unless arity <= 2
|
84
|
-
raise ArgumentError, "wrong number of block parameter #{arity} for 0..2"
|
80
|
+
@hash[:default_type] = type
|
81
|
+
@hash[:default_value] = value
|
85
82
|
end
|
86
|
-
end
|
87
83
|
|
88
|
-
|
89
|
-
|
90
|
-
@hash.freeze
|
91
|
-
ret
|
92
|
-
end
|
84
|
+
def check_default_lazy_proc(proc)
|
85
|
+
raise TypeError unless proc.respond_to?(:call)
|
93
86
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def initialize_copy(original)
|
103
|
-
ret = super original
|
104
|
-
@hash = @hash.dup
|
105
|
-
ret
|
106
|
-
end
|
87
|
+
arity = proc.arity
|
88
|
+
unless arity <= 2
|
89
|
+
raise ArgumentError, "wrong number of block parameter #{arity} for 0..2"
|
90
|
+
end
|
91
|
+
end
|
107
92
|
|
108
|
-
|
93
|
+
def freeze
|
94
|
+
ret = super
|
95
|
+
@hash.freeze
|
96
|
+
ret
|
97
|
+
end
|
98
|
+
|
99
|
+
def dup
|
100
|
+
ret = super
|
101
|
+
@hash = @hash.dup
|
102
|
+
ret
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def initialize_copy(original)
|
108
|
+
ret = super(original)
|
109
|
+
@hash = @hash.dup
|
110
|
+
ret
|
111
|
+
end
|
112
|
+
end
|
109
113
|
|
110
|
-
if respond_to? :private_constant
|
111
114
|
private_constant :Attributes
|
112
115
|
end
|
113
|
-
|
114
|
-
end; end
|
116
|
+
end
|
@@ -1,112 +1,115 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# @group Member Conflict Management
|
4
|
-
|
5
|
-
# @return [Hash] Symbol => Fixnum
|
6
|
-
NAMING_RISKS = {
|
7
|
-
conflict: 10,
|
8
|
-
no_identifier: 9,
|
9
|
-
bad_manners: 5,
|
10
|
-
no_ascii: 3,
|
11
|
-
strict: 0
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
# @return [Hash] Symbol => Hash
|
15
|
-
CONFLICT_MANAGEMENT_LEVELS = {
|
16
|
-
struct: {error: 99, warn: 99},
|
17
|
-
warning: {error: 99, warn: 5},
|
18
|
-
error: {error: 9, warn: 5},
|
19
|
-
prevent: {error: 5, warn: 1},
|
20
|
-
nervous: {error: 1, warn: 1}
|
21
|
-
}.each(&:freeze).freeze
|
22
|
-
|
23
|
-
# @return [Symbol]
|
24
|
-
DEFAULT_CONFLICT_MANAGEMENT_LEVEL = :prevent
|
25
|
-
|
26
|
-
# @param [Object] name
|
27
|
-
# accpeptable the name into own member, under protect level of runtime
|
28
|
-
def cname?(name)
|
29
|
-
_check_safety_naming(name.to_sym){|r|r}
|
30
|
-
rescue Exception
|
31
|
-
false
|
32
|
-
end
|
33
|
-
|
34
|
-
attr_reader :conflict_management_level
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
# @param [Symbol, String, #to_sym] level
|
39
|
-
# @return [Symbol] level
|
40
|
-
# change level of management conflict member names
|
41
|
-
def set_conflict_management_level(level)
|
42
|
-
level = level.to_sym
|
43
|
-
raise NameError unless CONFLICT_MANAGEMENT_LEVELS.has_key? level
|
44
|
-
|
45
|
-
@conflict_management_level = level
|
46
|
-
end
|
1
|
+
# frozen_string_literal: true
|
47
2
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
# @return [void]
|
52
|
-
# @raise [ArgumentError] if no block given
|
53
|
-
# temp scope of a conflict_management_level
|
54
|
-
def conflict_management(level=DEFAULT_CONFLICT_MANAGEMENT_LEVEL)
|
55
|
-
before = @conflict_management_level
|
56
|
-
set_conflict_management_level level
|
57
|
-
|
58
|
-
yield
|
59
|
-
ensure
|
60
|
-
@conflict_management_level = before
|
61
|
-
self
|
62
|
-
end
|
63
|
-
|
64
|
-
# @param [Symbol] name
|
65
|
-
# @return [void]
|
66
|
-
# @yieldreturn [Boolean]
|
67
|
-
def _check_safety_naming(name)
|
68
|
-
estimation = _estimate_naming name
|
69
|
-
risk = NAMING_RISKS.fetch estimation
|
70
|
-
plevels = CONFLICT_MANAGEMENT_LEVELS.fetch @conflict_management_level
|
71
|
-
caution = "undesirable naming '#{name}', because #{estimation}"
|
72
|
-
|
73
|
-
r = (
|
74
|
-
case
|
75
|
-
when risk >= plevels.fetch(:error)
|
76
|
-
raise NameError, caution unless block_given?
|
77
|
-
false
|
78
|
-
when risk >= plevels.fetch(:warn)
|
79
|
-
warn caution unless block_given?
|
80
|
-
false
|
81
|
-
else
|
82
|
-
true
|
83
|
-
end
|
84
|
-
)
|
3
|
+
class Striuct
|
4
|
+
module ClassMethods
|
5
|
+
# @group Member Conflict Management
|
85
6
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
7
|
+
# @return [Hash] Symbol => Fixnum
|
8
|
+
NAMING_RISKS = {
|
9
|
+
conflict: 10,
|
10
|
+
no_identifier: 9,
|
11
|
+
bad_manners: 5,
|
12
|
+
no_ascii: 3,
|
13
|
+
strict: 0
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
# @return [Hash] Symbol => Hash
|
17
|
+
CONFLICT_MANAGEMENT_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
|
+
# @return [Symbol]
|
26
|
+
DEFAULT_CONFLICT_MANAGEMENT_LEVEL = :prevent
|
27
|
+
|
28
|
+
# @param [Object] name
|
29
|
+
# acceptable the name into own member, under protect level of runtime
|
30
|
+
def cname?(name)
|
31
|
+
_check_safety_naming(name.to_sym) { |r| r }
|
32
|
+
rescue Exception
|
33
|
+
false
|
94
34
|
end
|
95
35
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
36
|
+
attr_reader :conflict_management_level
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# @param [Symbol, String, #to_sym] level
|
41
|
+
# @return [Symbol] level
|
42
|
+
# change level of management conflict member names
|
43
|
+
def set_conflict_management_level(level)
|
44
|
+
level = level.to_sym
|
45
|
+
raise NameError unless CONFLICT_MANAGEMENT_LEVELS.key?(level)
|
46
|
+
|
47
|
+
@conflict_management_level = level
|
107
48
|
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# @endgroup
|
111
49
|
|
112
|
-
|
50
|
+
# @param [Symbol, String, #to_sym] level
|
51
|
+
# @see [#set_conflict_management_level]
|
52
|
+
# @yieldreturn [self]
|
53
|
+
# @return [void]
|
54
|
+
# @raise [ArgumentError] if no block given
|
55
|
+
# temp scope of a conflict_management_level
|
56
|
+
def conflict_management(level=DEFAULT_CONFLICT_MANAGEMENT_LEVEL)
|
57
|
+
before = @conflict_management_level
|
58
|
+
set_conflict_management_level(level)
|
59
|
+
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
@conflict_management_level = before
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param [Symbol] name
|
67
|
+
# @return [void]
|
68
|
+
# @yieldreturn [Boolean]
|
69
|
+
def _check_safety_naming(name)
|
70
|
+
estimation = _estimate_naming(name)
|
71
|
+
risk = NAMING_RISKS.fetch(estimation)
|
72
|
+
plevels = CONFLICT_MANAGEMENT_LEVELS.fetch(@conflict_management_level)
|
73
|
+
caution = "undesirable naming '#{name}', because #{estimation}"
|
74
|
+
|
75
|
+
r = (
|
76
|
+
case
|
77
|
+
when risk >= plevels.fetch(:error)
|
78
|
+
raise NameError, caution unless block_given?
|
79
|
+
|
80
|
+
false
|
81
|
+
when risk >= plevels.fetch(:warn)
|
82
|
+
warn(caution) unless block_given?
|
83
|
+
false
|
84
|
+
else
|
85
|
+
true
|
86
|
+
end
|
87
|
+
)
|
88
|
+
|
89
|
+
yield r if block_given?
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param [Symbol] name
|
93
|
+
# @return [Symbol]
|
94
|
+
def _estimate_naming(name)
|
95
|
+
if (instance_methods + private_instance_methods).include?(name)
|
96
|
+
return :conflict
|
97
|
+
end
|
98
|
+
|
99
|
+
return :no_ascii unless name.encoding.equal?(Encoding::ASCII)
|
100
|
+
|
101
|
+
case name
|
102
|
+
when /\W/, /\A[^a-zA-Z_]/, :''
|
103
|
+
:no_identifier
|
104
|
+
when /\Aeach/, /\A__[^_]*__\z/, /\A_[^_]*\z/, /[!?]\z/, /\Ato_/
|
105
|
+
:bad_manners
|
106
|
+
when /\A[a-zA-Z_]\w*\z/
|
107
|
+
:strict
|
108
|
+
else
|
109
|
+
raise 'must not happen'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# @endgroup
|
114
|
+
end
|
115
|
+
end
|