comodule 0.0.4
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/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +278 -0
- data/Rakefile +6 -0
- data/comodule.gemspec +24 -0
- data/lib/comodule/config_support.rb +72 -0
- data/lib/comodule/customize_class/hash_custom.rb +20 -0
- data/lib/comodule/customize_class/string_custom.rb +129 -0
- data/lib/comodule/customize_class.rb +38 -0
- data/lib/comodule/uni_array.rb +21 -0
- data/lib/comodule/version.rb +3 -0
- data/lib/comodule.rb +13 -0
- data/spec/comodule/config_support_spec.rb +168 -0
- data/spec/comodule/customize_class/hash_custom_spec.rb +32 -0
- data/spec/comodule/customize_class/string_custom_spec.rb +42 -0
- data/spec/comodule/uni_array_spec.rb +39 -0
- data/spec/comodule_spec.rb +9 -0
- data/spec/spec_helper.rb +3 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fda5e5972ccfc052cf2bd83e2b68dbf65969fd3
|
4
|
+
data.tar.gz: cecaed5a265d776050d1cd107fe429eaa1482795
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 83a663b9a20534b3e7020516a89634e3d433306e9da169e99fe9e68a33553bade483e0949234cd5f3ce3ad87d4462bed0a6a3632e1d0562f75935c9711727ad0
|
7
|
+
data.tar.gz: 42b180d2dfda6868fb9cecac6ddae4afeb6720abe8b3f3b150bd75ec2d0a0b797f10ddfa076f7b3a318c5cc3fc61e30bdf63d1c41544fb79548d7a31ce6fa624
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Goto Kei, Zeneffect Inc.
|
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
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
comodule
|
2
|
+
========
|
3
|
+
|
4
|
+
今まで作って来た Rails プロジェクトで共通して使用しているコードを gem にします。
|
5
|
+
|
6
|
+
## 概要
|
7
|
+
|
8
|
+
* モジュール
|
9
|
+
* ConfigSupport
|
10
|
+
* UniArray
|
11
|
+
|
12
|
+
* クラスの拡張
|
13
|
+
* Hash
|
14
|
+
* pullout, pullout!
|
15
|
+
* String
|
16
|
+
* standardize
|
17
|
+
|
18
|
+
## モジュール
|
19
|
+
|
20
|
+
### ConfigSupport
|
21
|
+
|
22
|
+
定義なしにアトリビュートを保存できる初期情報などを扱うのに適した汎用オブジェクト。
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
config = Comodule::ConfigSupport::Config.new
|
26
|
+
config.host = 'example.com'
|
27
|
+
config.port = '3000'
|
28
|
+
|
29
|
+
config.host
|
30
|
+
# => "example.com"
|
31
|
+
|
32
|
+
config.port
|
33
|
+
# => "3000"
|
34
|
+
```
|
35
|
+
|
36
|
+
デフォルトでは、設定されていないディレクティブは nil を返します。
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
config.nothing
|
40
|
+
# => nil
|
41
|
+
```
|
42
|
+
|
43
|
+
設定されていないディレクティブにアクセスした場合に例外を挙げることもできます。
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
config = Comodule::ConfigSupport::Config.new(
|
47
|
+
configure_type: :hard,
|
48
|
+
host: 'example.com',
|
49
|
+
port: '3000'
|
50
|
+
)
|
51
|
+
config.nothing
|
52
|
+
# => ArgumentError: Comodole::ConfigSupport::Config is missing this directive [nothing].
|
53
|
+
```
|
54
|
+
|
55
|
+
`new` の引数に `Hash` が含まれる場合は、再帰的にオブジェクト化します。
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
config = Comodule::ConfigSupport::Config.new(
|
59
|
+
host: 'example.com',
|
60
|
+
port: '3000',
|
61
|
+
db: {
|
62
|
+
host: 'rds',
|
63
|
+
database: 'app_development',
|
64
|
+
username: 'ec2-user',
|
65
|
+
password: 'secret',
|
66
|
+
instance: {
|
67
|
+
type: 't1.micro',
|
68
|
+
multi_az: true
|
69
|
+
}
|
70
|
+
}
|
71
|
+
)
|
72
|
+
|
73
|
+
config.db.host
|
74
|
+
# => "rds"
|
75
|
+
|
76
|
+
config.db.instance.type
|
77
|
+
# => "t1.micro"
|
78
|
+
```
|
79
|
+
|
80
|
+
角括弧演算子を使えば、`Hash` のような振る舞いもします。
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
config = Comodule::ConfigSupport::Config.new
|
84
|
+
|
85
|
+
config[:host] = 'example.com'
|
86
|
+
|
87
|
+
config[:db] = {
|
88
|
+
host: 'rds',
|
89
|
+
username: 'ec2-user'
|
90
|
+
}
|
91
|
+
|
92
|
+
config[:db][:host]
|
93
|
+
# => "rds"
|
94
|
+
|
95
|
+
config.db.username
|
96
|
+
# => "ec2-user"
|
97
|
+
```
|
98
|
+
|
99
|
+
`Hash` に変換
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
config.to_hash
|
103
|
+
# => {:host=>"example.com", :port=>"3000"}
|
104
|
+
```
|
105
|
+
|
106
|
+
### UniArray
|
107
|
+
|
108
|
+
要素の重複をさせない `Array` のサブクラス。スニペットと言っていいくらい簡単なコードで出来ています。
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
arr = Comodule::UniArray.new
|
112
|
+
|
113
|
+
# 重複する要素は無視されます。
|
114
|
+
arr << "a"
|
115
|
+
arr << "b"
|
116
|
+
arr << "a"
|
117
|
+
arr << "c"
|
118
|
+
arr << "a" << "b" << "c"
|
119
|
+
# => ["a", "b", "c"]
|
120
|
+
```
|
121
|
+
|
122
|
+
`#max_size=` で要素数の上限を決めることもできます。`#max_size` を超えると、先頭が切り詰められます。
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
arr = Comodule::UniArray.new
|
126
|
+
arr.max_size = 5
|
127
|
+
|
128
|
+
arr << 1 << 2 << 3
|
129
|
+
arr << 1 << 2 << 3
|
130
|
+
|
131
|
+
arr << 4 << 5 << 6
|
132
|
+
arr << 4 << 5 << 6
|
133
|
+
|
134
|
+
arr << 7 << 8 << 9 << 10
|
135
|
+
# => [6, 7, 8, 9, 10]
|
136
|
+
```
|
137
|
+
|
138
|
+
`Array` の集合和演算を使えば済むことなので、`merge` はオーバーライドしていません。
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
arr1 = [1, 3, 4, 5]
|
142
|
+
arr2 = [2, 3, 5, 9]
|
143
|
+
|
144
|
+
# 集合和演算を使いましょう。
|
145
|
+
arr = Comodule::UniArray.new
|
146
|
+
arr += arr1
|
147
|
+
arr |= arr2
|
148
|
+
# => [1, 3, 4, 5, 2, 9]
|
149
|
+
```
|
150
|
+
|
151
|
+
## クラスの拡張
|
152
|
+
|
153
|
+
Comodule は、Hash と String の独自拡張を持っています。
|
154
|
+
利用するには `Comodule::CustomizeClass.customize` を使います。Rails の場合は、`config/initializers/comodule.rb` などに
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
Comodule::CustomizeClass.customize
|
158
|
+
```
|
159
|
+
|
160
|
+
として、読み込みます。このメソッドは複数回呼び出すとエラーになりますので、気をつけてください。
|
161
|
+
尚、Comodule は既存のメソッドをオーバーライドできません。
|
162
|
+
|
163
|
+
### Hash
|
164
|
+
|
165
|
+
#### pullout, pullout!
|
166
|
+
|
167
|
+
ハッシュから指定要素を抜き出して新しいハッシュを返す。
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
hsh = {
|
171
|
+
date: "20130322",
|
172
|
+
title: "The Tell-Tale Brain",
|
173
|
+
secret_token: "it-is-secret"
|
174
|
+
}
|
175
|
+
result_hsh = hsh.pullout(:date, :title)
|
176
|
+
# => {date: "20130322", title: "The Tell-Tale Brain"}
|
177
|
+
```
|
178
|
+
|
179
|
+
デフォルトでは未定義の要素は無視します。
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
hsh = {
|
183
|
+
date: "20130322",
|
184
|
+
title: "The Tell-Tale Brain",
|
185
|
+
secret_token: "it-is-secret"
|
186
|
+
}
|
187
|
+
result_hsh = hsh.pullout(:date, :title, :author)
|
188
|
+
# => {date: "20130322", title: "The Tell-Tale Brain"}
|
189
|
+
```
|
190
|
+
|
191
|
+
未定義要素へのアクセス時に例外を挙げたいときは `pullout!` を使います。
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
hsh = {
|
195
|
+
date: "20130322",
|
196
|
+
title: "The Tell-Tale Brain",
|
197
|
+
secret_token: "it-is-secret"
|
198
|
+
}
|
199
|
+
result_hsh = hsh.pullout!(:date, :title, :author)
|
200
|
+
# => ArgumentError: Comodule::CustomizeClass::HashCustom cannot find key 'author' is a Symbol.
|
201
|
+
```
|
202
|
+
|
203
|
+
### String
|
204
|
+
|
205
|
+
#### standardize
|
206
|
+
|
207
|
+
英数字記号などを半角に変換します。Ruby の標準添付ライブラリーに含まれる。`NKF` を利用します。変換のコアは以下のコードです。
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
after = NKF.nkf( '-Wwxm0Z0', NKF.nkf('-WwXm0', before) )
|
211
|
+
```
|
212
|
+
|
213
|
+
これだけだと `½` など、失われる文字がありますが、極力文字が失われないように工夫してあります。
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
txt = "Ruby 2.0.1−p451 ½"
|
217
|
+
txt.standardize
|
218
|
+
# => "Ruby 2.0.1-p451 ½"
|
219
|
+
```
|
220
|
+
|
221
|
+
半角カナは全角カナに変換されます。
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
txt = 'ドボウブシビテベカバナーバ'
|
225
|
+
txt.standardize
|
226
|
+
# => "ドボウブシビテベカバナーバ"
|
227
|
+
```
|
228
|
+
|
229
|
+
#### to_token
|
230
|
+
|
231
|
+
空白文字をワイルドカード `%` に置き換えて、検索文字列を作ります。
|
232
|
+
|
233
|
+
```ruby
|
234
|
+
search_word = "株 山 のり"
|
235
|
+
query_token = search_word.to_token
|
236
|
+
# => "株%山%のり%"
|
237
|
+
```
|
238
|
+
|
239
|
+
デフォルトでは前方一致から始まるけど、`prefix` に `%` を指定すれば、部分一致から開始することもできます。
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
search_word = "株 山 のり"
|
243
|
+
query_token = search_word.to_token(prefix: ?%)
|
244
|
+
# => "%株%山%のり%"
|
245
|
+
```
|
246
|
+
|
247
|
+
#### digitalize
|
248
|
+
|
249
|
+
数字以外の文字列を排除します。
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
tel = "01-2345-6789"
|
253
|
+
tel.digitalize
|
254
|
+
# => "0123456789"
|
255
|
+
|
256
|
+
# 全角でも大丈夫
|
257
|
+
tel = "01−2345−6789"
|
258
|
+
tel.digitalize
|
259
|
+
# => "0123456789"
|
260
|
+
```
|
261
|
+
|
262
|
+
#### その他 String の拡張
|
263
|
+
|
264
|
+
上記のミューテーター
|
265
|
+
|
266
|
+
* standardize!
|
267
|
+
* to_token!
|
268
|
+
* digitalize!
|
269
|
+
|
270
|
+
その他細々したメソッド
|
271
|
+
|
272
|
+
* ltrim, ltrim!
|
273
|
+
* rtrim, rtrim!
|
274
|
+
* trim, trim!
|
275
|
+
* ascii_space, ascii_space!
|
276
|
+
=> 全角スペースを半角スペースに
|
277
|
+
* single_space, single_space!
|
278
|
+
=> 全角、半角問わず複数のスペースを一つの半角スペースに
|
data/Rakefile
ADDED
data/comodule.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'comodule/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "comodule"
|
8
|
+
spec.version = Comodule::VERSION
|
9
|
+
spec.authors = ["Goto Kei"]
|
10
|
+
spec.email = ["kgoto@zeneffect.co.jp"]
|
11
|
+
spec.summary = %q{The useful library for Rails}
|
12
|
+
spec.description = %q{It is a library of the functions to be common by the Rails projects that we developed.}
|
13
|
+
spec.homepage = "https://github.com/zeneffect/comodule"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Comodule::ConfigSupport
|
2
|
+
class Config
|
3
|
+
def initialize(config_hash={})
|
4
|
+
config_hash[:configure_type] ||= :soft
|
5
|
+
config_hash.each do |directive, value|
|
6
|
+
value = value.to_sym if directive == :configure_type
|
7
|
+
if Hash === value
|
8
|
+
value[:configure_type] ||= config_hash[:configure_type]
|
9
|
+
value = self.class.new(value)
|
10
|
+
end
|
11
|
+
instance_variable_set "@#{directive}", value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(directive, arg=nil)
|
16
|
+
if directive =~ /^(.+)=/
|
17
|
+
arg = arg.to_sym if directive == :configure_type
|
18
|
+
if Hash === arg
|
19
|
+
arg[:configure_type] ||= configure_type
|
20
|
+
arg = self.class.new(arg)
|
21
|
+
end
|
22
|
+
arg = self.class.new(arg) if Hash === arg
|
23
|
+
return instance_variable_set("@#{$1}", arg)
|
24
|
+
end
|
25
|
+
value = instance_variable_get("@#{directive}")
|
26
|
+
if @configure_type == :hard && !value
|
27
|
+
raise ArgumentError, "Comodule::ConfigSupport::Config is missing this directive [#{directive}]."
|
28
|
+
end
|
29
|
+
value
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](directive)
|
33
|
+
send(directive)
|
34
|
+
end
|
35
|
+
|
36
|
+
def []=(directive, arg)
|
37
|
+
send("#{directive}=", arg)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_hash
|
41
|
+
hsh = {}
|
42
|
+
instance_variables.each do |variable_name|
|
43
|
+
next if variable_name == :@configure_type
|
44
|
+
key = variable_name.to_s.sub(/@/, '').to_sym
|
45
|
+
hsh[key] = instance_variable_get(variable_name)
|
46
|
+
end
|
47
|
+
hsh
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
module ClassMethods
|
53
|
+
def create_config(config_hash={})
|
54
|
+
Comodule::ConfigSupport::Config.new config_hash
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_config_hard(config_hash={})
|
58
|
+
config_hash[:configure_type] = :hard
|
59
|
+
create_config config_hash
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_config_soft(config_hash={})
|
63
|
+
config_hash[:configure_type] = :soft
|
64
|
+
create_config config_hash
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def self.included(receiver)
|
70
|
+
receiver.extend ClassMethods
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Comodule::CustomizeClass::HashCustom
|
2
|
+
|
3
|
+
# 指定したキーの組み合わせだけのハッシュを新たに作って返す。
|
4
|
+
# キーが見つからなくても無視する。
|
5
|
+
def pullout(*args)
|
6
|
+
args.inject({}) do |hsh, key|
|
7
|
+
hsh[key] = self[key] if self[key]
|
8
|
+
hsh
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# キーが見つからないときは例外を挙げる。
|
13
|
+
def pullout!(*args)
|
14
|
+
args.inject({}) do |hsh, key|
|
15
|
+
raise ArgumentError, "Comodule::CustomizeClass::HashCustom cannot find key '#{key}' is a #{key.class.name}." unless self[key]
|
16
|
+
hsh[key] = self[key]
|
17
|
+
hsh
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'nkf'
|
3
|
+
|
4
|
+
module Comodule::CustomizeClass::StringCustom
|
5
|
+
|
6
|
+
def ltrim
|
7
|
+
lstrip.sub(/^\p{Z}+/mu, '')
|
8
|
+
end
|
9
|
+
|
10
|
+
def ltrim!
|
11
|
+
str = ltrim
|
12
|
+
return nil if str == self
|
13
|
+
replace str
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def rtrim
|
18
|
+
rstrip.sub(/\p{Z}+$/mu, '')
|
19
|
+
end
|
20
|
+
|
21
|
+
def rtrim!
|
22
|
+
str = rtrim
|
23
|
+
return nil if str == self
|
24
|
+
replace str
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def trim
|
29
|
+
ltrim.rtrim
|
30
|
+
end
|
31
|
+
|
32
|
+
def trim!
|
33
|
+
str = trim
|
34
|
+
return nil if str == self
|
35
|
+
replace str
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def ascii_space
|
40
|
+
gsub(/\p{Z}/u, ?\s)
|
41
|
+
end
|
42
|
+
|
43
|
+
def ascii_space!
|
44
|
+
str = ascii_space
|
45
|
+
return nil if str == self
|
46
|
+
replace str
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# 全角または半角のスペースが連続する場合は一つの半角スペースにする。
|
51
|
+
def single_space
|
52
|
+
trim.gsub(/\p{Z}+/u, ?\s)
|
53
|
+
end
|
54
|
+
|
55
|
+
def single_space!
|
56
|
+
str = single_space
|
57
|
+
return nil if str == self
|
58
|
+
replace str
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# NKF.nkfで"½"などの文字が失われることがあるので、文字数が変化してしまったら一文字ずつの変換を行う。
|
63
|
+
# 半角カタカナの濁点、半濁点により文字数が変化した場合も一文字ずつの処理にする。
|
64
|
+
def standardize(_single_space=single_space)
|
65
|
+
before = _single_space || trim.ascii_space
|
66
|
+
after = NKF.nkf( '-Wwxm0Z0', NKF.nkf('-WwXm0', before) )
|
67
|
+
before.size == after.size ? after : standardize_delicate(_single_space)
|
68
|
+
end
|
69
|
+
|
70
|
+
# 1文字ずつ変換するので、当然パフォーマンスが低い。
|
71
|
+
def standardize_delicate(_single_space=single_space)
|
72
|
+
str = _single_space || trim.ascii_space
|
73
|
+
str_array = []
|
74
|
+
|
75
|
+
# 濁点と半濁点が一文字として変換されることを避ける。
|
76
|
+
str_chars = str.chars.to_enum
|
77
|
+
loop do
|
78
|
+
s = str_chars.next
|
79
|
+
# 濁点、半濁点は直前の文字と組み合わせる。
|
80
|
+
if !str_array.empty? && s =~ /(゙|゚)/
|
81
|
+
s = str_array.pop+s
|
82
|
+
end
|
83
|
+
str_array << s
|
84
|
+
end
|
85
|
+
|
86
|
+
re_str = ""
|
87
|
+
str_array.each do |char|
|
88
|
+
re_char = NKF.nkf( '-Wwxm0Z0', NKF.nkf('-WwXm0', char) )
|
89
|
+
re_str << (re_char.present? ? re_char : char)
|
90
|
+
end
|
91
|
+
re_str
|
92
|
+
end
|
93
|
+
|
94
|
+
def standardize!
|
95
|
+
str = standardize
|
96
|
+
return nil if str == self
|
97
|
+
replace str
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
# 空白文字をワイルドカードに置き換えて検索ワードを作る。
|
102
|
+
# ex. "株 山 のり" -> "株%山%のり%"
|
103
|
+
# デフォルトは前方一致、部分一致にしたければ:prefixに"%"を渡す。
|
104
|
+
def to_token(hsh={})
|
105
|
+
prefix = hsh[:prefix] || ""
|
106
|
+
suffix = hsh[:suffix] || ?%
|
107
|
+
str = sub(/^%+/,'').sub(/%+$/,'')
|
108
|
+
prefix + str.split(/\p{Z}+/u).join(?%) + suffix
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_token!(*args)
|
112
|
+
str = to_token(*args)
|
113
|
+
return nil if str == self
|
114
|
+
replace str
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def digitalize
|
119
|
+
standardize.gsub(/[^0-9]/,"")
|
120
|
+
end
|
121
|
+
|
122
|
+
def digitalize!
|
123
|
+
str = digitalize
|
124
|
+
return nil if str == self
|
125
|
+
replace str
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
|
3
|
+
module Comodule::CustomizeClass
|
4
|
+
|
5
|
+
class CustomizeClassError < StandardError; end
|
6
|
+
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# customize_classディレクトリにあるクラスで既存のクラスを拡張する。
|
10
|
+
# モジュールのパブリックメソッドとClassMethodsをチェックし、
|
11
|
+
# フレームワークに影響がないように、既に存在するメソッドのオーバーライドは許可しない。
|
12
|
+
def customize
|
13
|
+
Dir.glob(File.expand_path('../customize_class/*', __FILE__)).each do |path|
|
14
|
+
name = File.basename(path, "_custom.rb").classify
|
15
|
+
mod = "Comodule::CustomizeClass::#{name}Custom".constantize
|
16
|
+
klass = name.constantize
|
17
|
+
|
18
|
+
# パブリックメソッドのチェック
|
19
|
+
mod.public_instance_methods.each do |sym|
|
20
|
+
if klass.public_method_defined? sym
|
21
|
+
raise CustomizeClassError, "RubyまたはRailsで定義されている#{klass.name}##{sym}をオーバーライドしようとしています。"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
klass.send :include, mod
|
25
|
+
|
26
|
+
# クラスメソッドのチェック
|
27
|
+
if mod.constants.member?(:ClassMethods)
|
28
|
+
class_methods = "#{mod.name}::ClassMethods".constantize
|
29
|
+
class_methods.public_instance_methods.each do |sym|
|
30
|
+
if klass.singleton_methods.member?(sym)
|
31
|
+
raise CustomizeClassError, "RubyまたはRailsで定義されている#{klass.name}.#{sym}をオーバーライドしようとしています。"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
klass.extend class_methods
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Comodule
|
2
|
+
# .<<()で追加されるメンバが重複する場合は無視するArrayのサブクラス。
|
3
|
+
class UniArray < Array
|
4
|
+
attr_accessor :max_size
|
5
|
+
|
6
|
+
def <<(arg)
|
7
|
+
if member?(arg)
|
8
|
+
return self
|
9
|
+
end
|
10
|
+
|
11
|
+
super
|
12
|
+
|
13
|
+
# max_sizeに到達したら、先頭を切り詰めて返す。
|
14
|
+
if max_size && size > max_size
|
15
|
+
replace self[-max_size..-1]
|
16
|
+
end
|
17
|
+
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/comodule.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "comodule/version"
|
2
|
+
require "rails"
|
3
|
+
|
4
|
+
module Comodule
|
5
|
+
autoload :UniArray, 'comodule/uni_array'
|
6
|
+
autoload :ConfigSupport, 'comodule/config_support'
|
7
|
+
autoload :CustomizeClass, 'comodule/customize_class'
|
8
|
+
|
9
|
+
module CustomizeClass
|
10
|
+
autoload :HashCustom, 'comodule/customize_class/hash_custom'
|
11
|
+
autoload :StringCustom, 'comodule/customize_class/string_custom'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Comodule::ConfigSupport do
|
4
|
+
describe '::Config' do
|
5
|
+
context '#[], #[]=' do
|
6
|
+
it 'like Hash' do
|
7
|
+
config = Comodule::ConfigSupport::Config.new
|
8
|
+
config[:host] = 'example.com'
|
9
|
+
config[:port] = '3000'
|
10
|
+
|
11
|
+
expect(config[:host]).to eq('example.com')
|
12
|
+
expect(config[:port]).to eq('3000')
|
13
|
+
|
14
|
+
config[:db] = {
|
15
|
+
host: 'rds',
|
16
|
+
database: 'app_development',
|
17
|
+
password: 'secret'
|
18
|
+
}
|
19
|
+
|
20
|
+
expect(config[:db][:host]).to eq('rds')
|
21
|
+
expect(config[:db][:database]).to eq('app_development')
|
22
|
+
expect(config[:db][:password]).to eq('secret')
|
23
|
+
|
24
|
+
expect(config.db.host).to eq('rds')
|
25
|
+
expect(config.db.database).to eq('app_development')
|
26
|
+
expect(config.db.password).to eq('secret')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#to_hash' do
|
31
|
+
it 'not include :cofigure_type' do
|
32
|
+
config = Comodule::ConfigSupport::Config.new(
|
33
|
+
configure_type: :hard,
|
34
|
+
host: 'example.com',
|
35
|
+
port: '3000',
|
36
|
+
ip: '10.0.0.100'
|
37
|
+
)
|
38
|
+
expect(config.to_hash).to eq({
|
39
|
+
host: 'example.com',
|
40
|
+
port: '3000',
|
41
|
+
ip: '10.0.0.100'
|
42
|
+
})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context '.new' do
|
47
|
+
it 'can specify each other configure_type to recursive object' do
|
48
|
+
config = Comodule::ConfigSupport::Config.new(
|
49
|
+
configure_type: :hard,
|
50
|
+
host: 'example.com',
|
51
|
+
port: '3000',
|
52
|
+
db: {
|
53
|
+
host: 'rds',
|
54
|
+
database: 'app_development',
|
55
|
+
username: 'ec2-user',
|
56
|
+
password: 'secret'
|
57
|
+
}
|
58
|
+
)
|
59
|
+
expect(config.configure_type).to eq(:hard)
|
60
|
+
expect(config.db.configure_type).to eq(:hard)
|
61
|
+
|
62
|
+
config.current_user = {
|
63
|
+
role: 'admin',
|
64
|
+
dept: 'sales'
|
65
|
+
}
|
66
|
+
|
67
|
+
expect(config.current_user.configure_type).to eq(:hard)
|
68
|
+
|
69
|
+
config.current_user = {
|
70
|
+
configure_type: :soft,
|
71
|
+
role: 'admin',
|
72
|
+
dept: 'sales'
|
73
|
+
}
|
74
|
+
expect(config.configure_type).to eq(:hard)
|
75
|
+
expect(config.db.configure_type).to eq(:hard)
|
76
|
+
expect(config.current_user.configure_type).to eq(:soft)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'return recursive object when argument include Hash' do
|
80
|
+
config = Comodule::ConfigSupport::Config.new(
|
81
|
+
host: 'example.com',
|
82
|
+
port: '3000',
|
83
|
+
db: {
|
84
|
+
host: 'rds',
|
85
|
+
database: 'app_development',
|
86
|
+
username: 'ec2-user',
|
87
|
+
password: 'secret',
|
88
|
+
instance: {
|
89
|
+
type: 't1.micro',
|
90
|
+
multi_az: false
|
91
|
+
}
|
92
|
+
}
|
93
|
+
)
|
94
|
+
expect(config.db.host).to eq('rds')
|
95
|
+
expect(config.db.database).to eq('app_development')
|
96
|
+
expect(config.db.username).to eq('ec2-user')
|
97
|
+
expect(config.db.password).to eq('secret')
|
98
|
+
expect(config.db.instance.type).to eq('t1.micro')
|
99
|
+
expect(config.db.instance.multi_az).to eq(false)
|
100
|
+
|
101
|
+
config = Comodule::ConfigSupport::Config.new(
|
102
|
+
host: 'example.com',
|
103
|
+
port: '3000'
|
104
|
+
)
|
105
|
+
config.db = {
|
106
|
+
host: 'rds',
|
107
|
+
database: 'app_development',
|
108
|
+
username: 'ec2-user',
|
109
|
+
password: 'secret'
|
110
|
+
}
|
111
|
+
expect(config.db.host).to eq('rds')
|
112
|
+
expect(config.db.database).to eq('app_development')
|
113
|
+
expect(config.db.username).to eq('ec2-user')
|
114
|
+
expect(config.db.password).to eq('secret')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'useful configure object' do
|
118
|
+
config = Comodule::ConfigSupport::Config.new(
|
119
|
+
host: 'example.com',
|
120
|
+
port: '3000',
|
121
|
+
ip: '10.0.0.100'
|
122
|
+
)
|
123
|
+
expect(config.host).to eq('example.com')
|
124
|
+
expect(config.port).to eq('3000')
|
125
|
+
expect(config.ip).to eq('10.0.0.100')
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'return nil when access undefined attribute at default' do
|
129
|
+
config = Comodule::ConfigSupport::Config.new(
|
130
|
+
host: 'example.com',
|
131
|
+
port: '3000',
|
132
|
+
ip: '10.0.0.100'
|
133
|
+
)
|
134
|
+
expect(config.nothing).to eq(nil)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'raises error when access undefined attribute at the configure_type is :hard' do
|
138
|
+
config = Comodule::ConfigSupport::Config.new(
|
139
|
+
configure_type: :hard,
|
140
|
+
host: 'example.com',
|
141
|
+
port: '3000',
|
142
|
+
ip: '10.0.0.100'
|
143
|
+
)
|
144
|
+
expect{config.nothing}.to raise_error(ArgumentError)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
context '#create_config' do
|
152
|
+
before do
|
153
|
+
stub_const("SomeClass", Class.new)
|
154
|
+
SomeClass.send :include, Comodule::ConfigSupport
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'class configure' do
|
158
|
+
class SomeClass
|
159
|
+
Configure = create_config(
|
160
|
+
max_record_size: 3000,
|
161
|
+
update_index: 'some_class-20140325'
|
162
|
+
)
|
163
|
+
end
|
164
|
+
expect(SomeClass::Configure.max_record_size).to eq(3000)
|
165
|
+
expect(SomeClass::Configure.update_index).to eq('some_class-20140325')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Comodule::CustomizeClass::HashCustom do
|
5
|
+
context '#pullout' do
|
6
|
+
it 'create new hash with selected attributes' do
|
7
|
+
hsh = {
|
8
|
+
date: "20130322",
|
9
|
+
title: "The Tell-Tale Brain",
|
10
|
+
secret_token: "it-is-secret"
|
11
|
+
}
|
12
|
+
expect(hsh.pullout(:date, :title)).to eq({
|
13
|
+
date: "20130322",
|
14
|
+
title: "The Tell-Tale Brain"
|
15
|
+
})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#pullout!' do
|
20
|
+
it 'raise error when access a missing attribute' do
|
21
|
+
hsh = {
|
22
|
+
date: "20130322",
|
23
|
+
title: "The Tell-Tale Brain",
|
24
|
+
secret_token: "it-is-secret"
|
25
|
+
}
|
26
|
+
expect{hsh.pullout!(:date, :author)}.to raise_error(
|
27
|
+
ArgumentError,
|
28
|
+
/cannot find key 'author' is a Symbol/
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
|
6
|
+
describe Comodule::CustomizeClass::StringCustom do
|
7
|
+
context '#standardize' do
|
8
|
+
it 'converts alphanumeric to singlebyte charactors' do
|
9
|
+
txt = "Ruby 2.0.1−p451 ½"
|
10
|
+
expect(txt.standardize).to eq("Ruby 2.0.1-p451 ½")
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'support hankaku' do
|
14
|
+
txt = 'ドボウブシビテベカバナーバ'
|
15
|
+
expect(txt.standardize).to eq("ドボウブシビテベカバナーバ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#to_token' do
|
20
|
+
it 'convert spaces to wildcards' do
|
21
|
+
txt = "株 山 のり"
|
22
|
+
expect(txt.to_token).to eq("株%山%のり%")
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'partial match' do
|
26
|
+
txt = "株 山 のり"
|
27
|
+
expect(txt.to_token(prefix: ?%)).to eq("%株%山%のり%")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#digitalize' do
|
32
|
+
it 'become string into only digit' do
|
33
|
+
tel = "01-2345-6789"
|
34
|
+
expect(tel.digitalize).to eq('0123456789')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'support multi byte charactors' do
|
38
|
+
tel = "01−2345−6789"
|
39
|
+
expect(tel.digitalize).to eq('0123456789')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Comodule::UniArray do
|
4
|
+
it 'UniArray has only unique value' do
|
5
|
+
arr = Comodule::UniArray.new
|
6
|
+
arr << "a"
|
7
|
+
arr << "b"
|
8
|
+
arr << "a"
|
9
|
+
arr << "c"
|
10
|
+
arr << "a" << "b" << "c"
|
11
|
+
expect(arr.size).to eq(3)
|
12
|
+
expect(arr).to eq(["a", "b", "c"])
|
13
|
+
end
|
14
|
+
|
15
|
+
it '#max_size' do
|
16
|
+
arr = Comodule::UniArray.new
|
17
|
+
arr.max_size = 5
|
18
|
+
arr << 1
|
19
|
+
arr << 2
|
20
|
+
arr << 3
|
21
|
+
|
22
|
+
arr << 1
|
23
|
+
arr << 2
|
24
|
+
arr << 3
|
25
|
+
|
26
|
+
arr << 4
|
27
|
+
arr << 5
|
28
|
+
arr << 6
|
29
|
+
|
30
|
+
arr << 4
|
31
|
+
arr << 5
|
32
|
+
arr << 6
|
33
|
+
|
34
|
+
arr << 7 << 8 << 9 << 10
|
35
|
+
|
36
|
+
expect(arr.size).to eq(5)
|
37
|
+
expect(arr).to eq([6, 7, 8, 9, 10])
|
38
|
+
end
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: comodule
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Goto Kei
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: It is a library of the functions to be common by the Rails projects that
|
56
|
+
we developed.
|
57
|
+
email:
|
58
|
+
- kgoto@zeneffect.co.jp
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- .rspec
|
65
|
+
- .travis.yml
|
66
|
+
- Gemfile
|
67
|
+
- LICENSE
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- comodule.gemspec
|
71
|
+
- lib/comodule.rb
|
72
|
+
- lib/comodule/config_support.rb
|
73
|
+
- lib/comodule/customize_class.rb
|
74
|
+
- lib/comodule/customize_class/hash_custom.rb
|
75
|
+
- lib/comodule/customize_class/string_custom.rb
|
76
|
+
- lib/comodule/uni_array.rb
|
77
|
+
- lib/comodule/version.rb
|
78
|
+
- spec/comodule/config_support_spec.rb
|
79
|
+
- spec/comodule/customize_class/hash_custom_spec.rb
|
80
|
+
- spec/comodule/customize_class/string_custom_spec.rb
|
81
|
+
- spec/comodule/uni_array_spec.rb
|
82
|
+
- spec/comodule_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
84
|
+
homepage: https://github.com/zeneffect/comodule
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.0.14
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: The useful library for Rails
|
108
|
+
test_files:
|
109
|
+
- spec/comodule/config_support_spec.rb
|
110
|
+
- spec/comodule/customize_class/hash_custom_spec.rb
|
111
|
+
- spec/comodule/customize_class/string_custom_spec.rb
|
112
|
+
- spec/comodule/uni_array_spec.rb
|
113
|
+
- spec/comodule_spec.rb
|
114
|
+
- spec/spec_helper.rb
|