striuct 0.3.3 → 0.3.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.
Files changed (88) hide show
  1. data/.gitignore +35 -34
  2. data/.travis.yml +6 -6
  3. data/Gemfile +12 -12
  4. data/History.rdoc +279 -273
  5. data/LICENSE +21 -21
  6. data/Manifest.txt +91 -90
  7. data/README.ja.old.rdoc +297 -297
  8. data/README.md +128 -128
  9. data/Rakefile +11 -11
  10. data/benchmark/basics.rb +56 -56
  11. data/example/README.rb +44 -44
  12. data/example/example.old.rdoc +187 -187
  13. data/example/example1.rb +233 -233
  14. data/example/example2.rb +22 -22
  15. data/example/see_trace.rb +32 -32
  16. data/lib/striuct/classmethods/README.md +5 -5
  17. data/lib/striuct/classmethods/adjustment.rb +32 -32
  18. data/lib/striuct/classmethods/constructor.rb +63 -63
  19. data/lib/striuct/classmethods/default.rb +27 -27
  20. data/lib/striuct/classmethods/enum.rb +48 -48
  21. data/lib/striuct/classmethods/inner.rb +91 -91
  22. data/lib/striuct/classmethods/length.rb +14 -14
  23. data/lib/striuct/classmethods/macro.rb +144 -144
  24. data/lib/striuct/classmethods/named.rb +113 -113
  25. data/lib/striuct/classmethods/object.rb +54 -54
  26. data/lib/striuct/classmethods/prevent_conflicts.rb +89 -89
  27. data/lib/striuct/classmethods/requiremnets.rb +11 -11
  28. data/lib/striuct/classmethods/to_struct.rb +23 -25
  29. data/lib/striuct/classmethods/validation.rb +55 -55
  30. data/lib/striuct/classmethods.rb +1 -1
  31. data/lib/striuct/instancemethods/README.md +5 -5
  32. data/lib/striuct/instancemethods/assign.rb +30 -30
  33. data/lib/striuct/instancemethods/cast.rb +34 -34
  34. data/lib/striuct/instancemethods/compare.rb +30 -30
  35. data/lib/striuct/instancemethods/default.rb +13 -13
  36. data/lib/striuct/instancemethods/delegate_class_methods.rb +28 -28
  37. data/lib/striuct/instancemethods/enum.rb +103 -103
  38. data/lib/striuct/instancemethods/hashy.rb +121 -121
  39. data/lib/striuct/instancemethods/inner.rb +60 -60
  40. data/lib/striuct/instancemethods/keyvalidatable.rb +14 -14
  41. data/lib/striuct/instancemethods/lock.rb +61 -61
  42. data/lib/striuct/instancemethods/object.rb +52 -52
  43. data/lib/striuct/instancemethods/requirements.rb +14 -14
  44. data/lib/striuct/instancemethods/safety.rb +11 -11
  45. data/lib/striuct/instancemethods/subscript.rb +55 -55
  46. data/lib/striuct/instancemethods/validation.rb +29 -25
  47. data/lib/striuct/instancemethods/values.rb +57 -57
  48. data/lib/striuct/instancemethods.rb +1 -1
  49. data/lib/striuct/requirements.rb +5 -5
  50. data/lib/striuct/singleton_class.rb +66 -66
  51. data/lib/striuct/specificcontainer.rb +19 -19
  52. data/lib/striuct/structs.rb +7 -7
  53. data/lib/striuct/version.rb +5 -5
  54. data/lib/striuct.rb +13 -13
  55. data/striuct.gemspec +24 -24
  56. data/test/helper.rb +5 -5
  57. data/test/test_striuct-singleton_class-define.rb +19 -19
  58. data/test/test_striuct-subclass-class-cloning.rb +20 -20
  59. data/test/test_striuct-subclass-class-close.rb +36 -36
  60. data/test/test_striuct-subclass-class-constructor.rb +82 -82
  61. data/test/test_striuct-subclass-class-freeze.rb +36 -36
  62. data/test/test_striuct-subclass-class-inheritable.rb +57 -57
  63. data/test/test_striuct-subclass-class-macro.rb +13 -13
  64. data/test/test_striuct-subclass-class-safety_naming.rb +72 -72
  65. data/test/test_striuct-subclass-class-validation.rb +26 -26
  66. data/test/test_striuct-subclass-feature-alias_member.rb +53 -53
  67. data/test/test_striuct-subclass-feature-to_struct.rb +61 -25
  68. data/test/test_striuct-subclass-feature-validation_util.rb +57 -0
  69. data/test/test_striuct-subclass-instance-accessor.rb +137 -137
  70. data/test/test_striuct-subclass-instance-adjuster.rb +94 -94
  71. data/test/test_striuct-subclass-instance-assign.rb +30 -30
  72. data/test/test_striuct-subclass-instance-basic.rb +32 -32
  73. data/test/test_striuct-subclass-instance-cloning.rb +22 -22
  74. data/test/test_striuct-subclass-instance-compare.rb +51 -51
  75. data/test/test_striuct-subclass-instance-default_value.rb +128 -128
  76. data/test/test_striuct-subclass-instance-enum.rb +92 -92
  77. data/test/test_striuct-subclass-instance-freeze.rb +19 -19
  78. data/test/test_striuct-subclass-instance-hashlike.rb +153 -153
  79. data/test/test_striuct-subclass-instance-keyvalidatable.rb +24 -24
  80. data/test/test_striuct-subclass-instance-lock.rb +39 -39
  81. data/test/test_striuct-subclass-instance-to_s_family.rb +25 -25
  82. data/test/test_striuct-subclass-instance-validation_functional_condition.rb +50 -50
  83. data/test/test_striuct-subclass-instance-validation_inference.rb +50 -50
  84. data/test/test_striuct-subclass-instance-validation_specific_conditions.rb +247 -247
  85. data/test/test_striuct-subclass-instance-validation_with_getter.rb +33 -33
  86. data/test/test_striuct-subclass-instance_names.rb +18 -18
  87. data/test/test_striuct-version.rb +10 -10
  88. metadata +4 -2
data/README.ja.old.rdoc CHANGED
@@ -1,298 +1,298 @@
1
- = Striuct
2
-
3
- * http://github.com/kachick/striuct
4
- * https://rubygems.org/gems/striuct
5
- * http://rubyforge.org/projects/striuct
6
-
7
- == DESCRIPTION
8
-
9
- Structっぽい手触りで扱える、多機能なStructを目指しています。
10
-
11
- メンバ名にチェックがかかる&一つの新しいクラスとして扱えるStructは、場面によってはHashよりも好ましい事があるかと思います。
12
- でもそうやってStructを使うぐらいなわけだから、値の方にもある程度のチェックをかけたいと思う事が多くありませんか?
13
-
14
- RubyのStructを愛しつつも、こういった部分をなんとかしたいと感じている方へお勧めします。
15
-
16
- 1. ノーガードで参照を付けられるのがおっかないときもある
17
- 2. かといって、型チェックしか出来ないようじゃRubyのメリットが死ぬんではなかろうか
18
- 3. メンバ名でフツーのメソッド名を上書きしかねないのもおっかない
19
- 4. 最初に代入したオブジェクトのクラスで固定したい(これは無いか)
20
- 5. どうせなら、チェックだけじゃなくキャストなりやらせたものを参照したい
21
- 6. メンバによっては標準値も定義したい
22
- 7. Hashとの親和性を高くしたい
23
- 8. メンバ名にaliasかけたいけど、alias_methodだけだと添え字アクセス出来なくて歯がゆい
24
- 9. 構造体クラスでも継承を使った上で、更にメンバ追加がしたい
25
-
26
- == FEATURES
27
-
28
- * メンバ毎に、参照条件を簡単に定義できます。
29
- * 型チェックではなく式チェックなので、動的型の良さを殺しません
30
- * Proc(lambda)やMethod等 を使うことで、さらに柔軟なチェックが可能です
31
- * どれか一つの構造体で最初に代入したオブジェクトのクラスに沿うようなメンバを作れます。
32
- * 参照直前に、ちょっとした処理を加える事も可能です
33
- * 構造体としてのメンバ追加時、Rubyの既存メソッドと干渉しないかを指定レベル別にチェック出来ます。
34
- * 違和感のない継承利用
35
- * なるべくStructの心地よい操作感を残したまま機能追加をしています。
36
- * 既存クラスやメソッドの上書き等をしない、控えめな名前空間
37
- * Pure Ruby
38
-
39
- == SYNOPSIS
40
-
41
- * setup
42
- require 'striuct'
43
-
44
- * この名前空間以外は汚しません。
45
- Striuct
46
-
47
- === Struct+ "Safety"
48
-
49
- ==== 基本的な使い方
50
-
51
- * memberというクラスマクロを使うことで構造体のメンバを定義できます。
52
- 引数2以降に、参照するための「条件」を渡して下さい。
53
- 何も条件を渡さなければ、Struct同様ノーチェックです。
54
- class User < Striuct.new
55
- member :id, Integer
56
- member :age, (20..140)
57
- member :name, OR(/\A\w+\z/, /\A\w+ \w+\z/)
58
- end
59
-
60
- # pass
61
- user = User.new 128381, 20
62
-
63
- # pass
64
- user.age = 30
65
- user[2] = 'taro yamada'
66
-
67
- # fail
68
- user[:id] = 10.0
69
- user.age = 19
70
- user[2] = nil
71
-
72
-
73
- * 更に柔軟なチェッカが必要であれば関数的なオブジェクトを使って下さい。
74
- この時Proc(lambda)を構造体インスタンスのコンテキストで評価する為、他のメンバと連携したチェックも簡単です。
75
- module Game
76
- class Character
77
- end
78
-
79
- class DB < Striuct.new
80
- member :monsters, ->list{(list - characters).empty?}
81
- member :characters, GENERICS(Character)
82
- end
83
-
84
- monster = Character.new
85
- db = DB.new
86
-
87
- # fail
88
- db.characters = [1, 2]
89
-
90
- # pass
91
- db.characters = [monster, Character.new]
92
-
93
- # fail
94
- db.monsters = [:Character.new]
95
-
96
- # pass
97
- db.monsters = [monster]
98
- end
99
-
100
- * オプションパラメータにinferenceというキーワードをtrueで渡すと、
101
- 最初に参照したオブジェクトのクラスが以降全インスタンスでの参照条件となります。
102
- class FlexibleContainer < Striuct.new
103
- member :anything, anything, inference: true
104
- member :number, Numeric, inference: true
105
- end
106
-
107
- fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
108
- # pass
109
- fc1.anything = 'str'
110
-
111
- # fail
112
- fc1.anything = :sym
113
- fc2.anything = :sym
114
-
115
- # pass
116
- fc2.anything = 'string too'
117
-
118
- # fail
119
- fc1.number = 'str'
120
-
121
- # pass
122
- fc1.number = 1.0
123
-
124
- # fail
125
- fc2.number = 1
126
-
127
- ==== 意図しない名前干渉は避ける
128
-
129
- * Structはこんな感じで、ノーガード上書き&メソッド定義出来ない物も無警告で進みます(object_id, __id__ なんかもそうですね)
130
- NoGuard = Struct.new :__send__, :'? !'
131
- noguard = NoGuard.new false
132
- p noguard.__send__
133
- p noguard.methods.include?(:'? !') # lost!!
134
-
135
- * ということで、意図しない上書き等を防ぐために安全度を設定出来るようにしました。
136
- 標準値は上から2番目の「:prevent」です。
137
- class SafetyNaming < Striuct.new
138
- begin
139
- member :__send__
140
- rescue
141
- p $!
142
- end
143
-
144
- begin
145
- member :'? !'
146
- rescue
147
- p $!
148
- end
149
-
150
- # ここで下げると、定義可能に
151
- protect_level :struct
152
-
153
- member :__send__, :'? !'
154
- end
155
-
156
- ==== この辺に関わる述語メソッド
157
-
158
- * valid? / acccept? / sufficient? # そのメンバにその値が設定出来るか
159
- * conditionable? # 条件式として受け入れ可能なオブジェクトか
160
- * inference? # 定義時にinferenceを使った上で、一つも参照されていないか
161
- * restrict? # そのメンバに参照条件がかけられているか
162
- * strict? # 今時点で全てのメンバが参照条件を満たしているか
163
- * secure? # インスタンスもクラスも変動することない状態で、インスタンスにfreezeがかかっているか
164
- * cname? # そのメンバ名は、今のprotect level下で望ましいものか
165
-
166
-
167
- === Struct+ "Handy"
168
-
169
- ==== Flavor
170
-
171
- * memberマクロへブロックを渡しておくと、チェック後一処理加えた値を参照可能です。
172
- class User2 < Striuct.new
173
- # 必ずInteger経由でキャスト
174
- member :age, Fixnum, &->v{Integer v}
175
-
176
- # Symbolに変換した上で代入。
177
- member :name, Symbol, &->v{v.to_s.to_sym}
178
- end
179
-
180
- user2 = User2.new
181
- user2.age = 9 #=> 9(Fixnum)
182
- user2.age = 10.1 #=> 10(Fixnum)
183
- user2.age = '10' #=> 10(Fixnum)
184
-
185
- user2.name = 10 #=> :10(Symbol)
186
- user2.name = Class #=> :Class(Symbol)
187
-
188
- ==== Default
189
-
190
- * defaultマクロを用いることで、メンバ毎に標準値を定義することが出来ます。
191
- ブロックを渡すと、初期化時にブロックの中身を評価して設定します。(Hash.newっぽく)
192
- class User3 < Striuct.new
193
- member :lank, Fixnum
194
- default :lank, 3
195
- member :name
196
- end
197
-
198
- user3 = User3.new
199
- user3.lank #=> 3
200
-
201
- * 「意図的なnil」との区別を付けられます。
202
- user3.name #=> nil
203
- user3.assign? :name #=> false
204
- user3.name = nil
205
- user3.assign? :name #=> true
206
-
207
- ==== Alias
208
-
209
- * メンバ名を付与出来ます。(標準Structだと、添字アクセス可能にしたりするのが面倒。)
210
- class User3
211
- alias_member :position, :lank
212
- end
213
-
214
- user3.lank.equal? user3.position #=> true
215
- user3[:lank].equal? user3[:position] #=> true
216
- user3[:position] = 4
217
- user3.lank #=> 4
218
-
219
- ==== Inherit
220
-
221
- * (writing...)
222
-
223
- ==== Lock
224
-
225
- * (writing...)
226
-
227
- ==== New Constructors
228
-
229
- * Subclass.define は、生成時から先オブジェクトを変える必要が無いケースで使います。
230
- * ブロックパラメータに新しいインスタンスがわたり、またこれが返り値となります
231
- * すべてのメンバがアサイン済みかをチェックします
232
- * ブロックを抜ける直前に、全て問題ない値かチェックします(オプション指定可)
233
- * ブロックを抜ける直前に、全てlockをかけます(オプション指定可)
234
- user3 = User3.define do |r|
235
- r.lank = 10
236
- r.name = 'foo'
237
- end
238
-
239
- * Subclass.[](load_pairs) は、HashなりHashっぽいものから作る時用です。
240
- # Struct.[] の仕様とは異なります。
241
- user3 = User3[lank:10, name: 'foo']
242
-
243
- === Structの良さは活かしたまま
244
-
245
- * 基本的にはStruct使い(?)が余り違和感を感じ無いようにしたつもりです。
246
- Sth2 = Striuct.new do
247
- def my_special_method
248
- end
249
- end
250
-
251
- Sth2.new.respond_to?(:my_special_method) #=> true
252
-
253
- === Hashとお近づきに
254
-
255
- * どちらかというとStructはHashよりArray寄りな感じを受けるのですが、個人的にHash的な動きをしてくれると嬉しい事の方が多く感じます。
256
- ということで、やり過ぎない範囲でHashっぽく使えるように調整しています。
257
-
258
- * Hashへの変換も一発です。
259
- user3.to_h #=> {:lank=>3, :name=>nil}
260
-
261
- == Note
262
-
263
- * 現状、このReadme含めてドキュメントは殆ど更新出来ていません。
264
-
265
- == REQUIREMENTS
266
-
267
- === Ruby
268
-
269
- * Ruby 1.9.2 and later (tested 1.9.2, 1.9.3)
270
-
271
- == INSTALL
272
-
273
- * sudo gem install striuct
274
-
275
- == LICENSE
276
-
277
- (The MIT License)
278
-
279
- Copyright (c) 2011 Kenichi Kamiya
280
-
281
- Permission is hereby granted, free of charge, to any person obtaining
282
- a copy of this software and associated documentation files (the
283
- 'Software'), to deal in the Software without restriction, including
284
- without limitation the rights to use, copy, modify, merge, publish,
285
- distribute, sublicense, and/or sell copies of the Software, and to
286
- permit persons to whom the Software is furnished to do so, subject to
287
- the following conditions:
288
-
289
- The above copyright notice and this permission notice shall be
290
- included in all copies or substantial portions of the Software.
291
-
292
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
293
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
294
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
295
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
296
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
297
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1
+ = Striuct
2
+
3
+ * http://github.com/kachick/striuct
4
+ * https://rubygems.org/gems/striuct
5
+ * http://rubyforge.org/projects/striuct
6
+
7
+ == DESCRIPTION
8
+
9
+ Structっぽい手触りで扱える、多機能なStructを目指しています。
10
+
11
+ メンバ名にチェックがかかる&一つの新しいクラスとして扱えるStructは、場面によってはHashよりも好ましい事があるかと思います。
12
+ でもそうやってStructを使うぐらいなわけだから、値の方にもある程度のチェックをかけたいと思う事が多くありませんか?
13
+
14
+ RubyのStructを愛しつつも、こういった部分をなんとかしたいと感じている方へお勧めします。
15
+
16
+ 1. ノーガードで参照を付けられるのがおっかないときもある
17
+ 2. かといって、型チェックしか出来ないようじゃRubyのメリットが死ぬんではなかろうか
18
+ 3. メンバ名でフツーのメソッド名を上書きしかねないのもおっかない
19
+ 4. 最初に代入したオブジェクトのクラスで固定したい(これは無いか)
20
+ 5. どうせなら、チェックだけじゃなくキャストなりやらせたものを参照したい
21
+ 6. メンバによっては標準値も定義したい
22
+ 7. Hashとの親和性を高くしたい
23
+ 8. メンバ名にaliasかけたいけど、alias_methodだけだと添え字アクセス出来なくて歯がゆい
24
+ 9. 構造体クラスでも継承を使った上で、更にメンバ追加がしたい
25
+
26
+ == FEATURES
27
+
28
+ * メンバ毎に、参照条件を簡単に定義できます。
29
+ * 型チェックではなく式チェックなので、動的型の良さを殺しません
30
+ * Proc(lambda)やMethod等 を使うことで、さらに柔軟なチェックが可能です
31
+ * どれか一つの構造体で最初に代入したオブジェクトのクラスに沿うようなメンバを作れます。
32
+ * 参照直前に、ちょっとした処理を加える事も可能です
33
+ * 構造体としてのメンバ追加時、Rubyの既存メソッドと干渉しないかを指定レベル別にチェック出来ます。
34
+ * 違和感のない継承利用
35
+ * なるべくStructの心地よい操作感を残したまま機能追加をしています。
36
+ * 既存クラスやメソッドの上書き等をしない、控えめな名前空間
37
+ * Pure Ruby
38
+
39
+ == SYNOPSIS
40
+
41
+ * setup
42
+ require 'striuct'
43
+
44
+ * この名前空間以外は汚しません。
45
+ Striuct
46
+
47
+ === Struct+ "Safety"
48
+
49
+ ==== 基本的な使い方
50
+
51
+ * memberというクラスマクロを使うことで構造体のメンバを定義できます。
52
+ 引数2以降に、参照するための「条件」を渡して下さい。
53
+ 何も条件を渡さなければ、Struct同様ノーチェックです。
54
+ class User < Striuct.new
55
+ member :id, Integer
56
+ member :age, (20..140)
57
+ member :name, OR(/\A\w+\z/, /\A\w+ \w+\z/)
58
+ end
59
+
60
+ # pass
61
+ user = User.new 128381, 20
62
+
63
+ # pass
64
+ user.age = 30
65
+ user[2] = 'taro yamada'
66
+
67
+ # fail
68
+ user[:id] = 10.0
69
+ user.age = 19
70
+ user[2] = nil
71
+
72
+
73
+ * 更に柔軟なチェッカが必要であれば関数的なオブジェクトを使って下さい。
74
+ この時Proc(lambda)を構造体インスタンスのコンテキストで評価する為、他のメンバと連携したチェックも簡単です。
75
+ module Game
76
+ class Character
77
+ end
78
+
79
+ class DB < Striuct.new
80
+ member :monsters, ->list{(list - characters).empty?}
81
+ member :characters, GENERICS(Character)
82
+ end
83
+
84
+ monster = Character.new
85
+ db = DB.new
86
+
87
+ # fail
88
+ db.characters = [1, 2]
89
+
90
+ # pass
91
+ db.characters = [monster, Character.new]
92
+
93
+ # fail
94
+ db.monsters = [:Character.new]
95
+
96
+ # pass
97
+ db.monsters = [monster]
98
+ end
99
+
100
+ * オプションパラメータにinferenceというキーワードをtrueで渡すと、
101
+ 最初に参照したオブジェクトのクラスが以降全インスタンスでの参照条件となります。
102
+ class FlexibleContainer < Striuct.new
103
+ member :anything, anything, inference: true
104
+ member :number, Numeric, inference: true
105
+ end
106
+
107
+ fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
108
+ # pass
109
+ fc1.anything = 'str'
110
+
111
+ # fail
112
+ fc1.anything = :sym
113
+ fc2.anything = :sym
114
+
115
+ # pass
116
+ fc2.anything = 'string too'
117
+
118
+ # fail
119
+ fc1.number = 'str'
120
+
121
+ # pass
122
+ fc1.number = 1.0
123
+
124
+ # fail
125
+ fc2.number = 1
126
+
127
+ ==== 意図しない名前干渉は避ける
128
+
129
+ * Structはこんな感じで、ノーガード上書き&メソッド定義出来ない物も無警告で進みます(object_id, __id__ なんかもそうですね)
130
+ NoGuard = Struct.new :__send__, :'? !'
131
+ noguard = NoGuard.new false
132
+ p noguard.__send__
133
+ p noguard.methods.include?(:'? !') # lost!!
134
+
135
+ * ということで、意図しない上書き等を防ぐために安全度を設定出来るようにしました。
136
+ 標準値は上から2番目の「:prevent」です。
137
+ class SafetyNaming < Striuct.new
138
+ begin
139
+ member :__send__
140
+ rescue
141
+ p $!
142
+ end
143
+
144
+ begin
145
+ member :'? !'
146
+ rescue
147
+ p $!
148
+ end
149
+
150
+ # ここで下げると、定義可能に
151
+ protect_level :struct
152
+
153
+ member :__send__, :'? !'
154
+ end
155
+
156
+ ==== この辺に関わる述語メソッド
157
+
158
+ * valid? / acccept? / sufficient? # そのメンバにその値が設定出来るか
159
+ * conditionable? # 条件式として受け入れ可能なオブジェクトか
160
+ * inference? # 定義時にinferenceを使った上で、一つも参照されていないか
161
+ * restrict? # そのメンバに参照条件がかけられているか
162
+ * strict? # 今時点で全てのメンバが参照条件を満たしているか
163
+ * secure? # インスタンスもクラスも変動することない状態で、インスタンスにfreezeがかかっているか
164
+ * cname? # そのメンバ名は、今のprotect level下で望ましいものか
165
+
166
+
167
+ === Struct+ "Handy"
168
+
169
+ ==== Flavor
170
+
171
+ * memberマクロへブロックを渡しておくと、チェック後一処理加えた値を参照可能です。
172
+ class User2 < Striuct.new
173
+ # 必ずInteger経由でキャスト
174
+ member :age, Fixnum, &->v{Integer v}
175
+
176
+ # Symbolに変換した上で代入。
177
+ member :name, Symbol, &->v{v.to_s.to_sym}
178
+ end
179
+
180
+ user2 = User2.new
181
+ user2.age = 9 #=> 9(Fixnum)
182
+ user2.age = 10.1 #=> 10(Fixnum)
183
+ user2.age = '10' #=> 10(Fixnum)
184
+
185
+ user2.name = 10 #=> :10(Symbol)
186
+ user2.name = Class #=> :Class(Symbol)
187
+
188
+ ==== Default
189
+
190
+ * defaultマクロを用いることで、メンバ毎に標準値を定義することが出来ます。
191
+ ブロックを渡すと、初期化時にブロックの中身を評価して設定します。(Hash.newっぽく)
192
+ class User3 < Striuct.new
193
+ member :lank, Fixnum
194
+ default :lank, 3
195
+ member :name
196
+ end
197
+
198
+ user3 = User3.new
199
+ user3.lank #=> 3
200
+
201
+ * 「意図的なnil」との区別を付けられます。
202
+ user3.name #=> nil
203
+ user3.assign? :name #=> false
204
+ user3.name = nil
205
+ user3.assign? :name #=> true
206
+
207
+ ==== Alias
208
+
209
+ * メンバ名を付与出来ます。(標準Structだと、添字アクセス可能にしたりするのが面倒。)
210
+ class User3
211
+ alias_member :position, :lank
212
+ end
213
+
214
+ user3.lank.equal? user3.position #=> true
215
+ user3[:lank].equal? user3[:position] #=> true
216
+ user3[:position] = 4
217
+ user3.lank #=> 4
218
+
219
+ ==== Inherit
220
+
221
+ * (writing...)
222
+
223
+ ==== Lock
224
+
225
+ * (writing...)
226
+
227
+ ==== New Constructors
228
+
229
+ * Subclass.define は、生成時から先オブジェクトを変える必要が無いケースで使います。
230
+ * ブロックパラメータに新しいインスタンスがわたり、またこれが返り値となります
231
+ * すべてのメンバがアサイン済みかをチェックします
232
+ * ブロックを抜ける直前に、全て問題ない値かチェックします(オプション指定可)
233
+ * ブロックを抜ける直前に、全てlockをかけます(オプション指定可)
234
+ user3 = User3.define do |r|
235
+ r.lank = 10
236
+ r.name = 'foo'
237
+ end
238
+
239
+ * Subclass.[](load_pairs) は、HashなりHashっぽいものから作る時用です。
240
+ # Struct.[] の仕様とは異なります。
241
+ user3 = User3[lank:10, name: 'foo']
242
+
243
+ === Structの良さは活かしたまま
244
+
245
+ * 基本的にはStruct使い(?)が余り違和感を感じ無いようにしたつもりです。
246
+ Sth2 = Striuct.new do
247
+ def my_special_method
248
+ end
249
+ end
250
+
251
+ Sth2.new.respond_to?(:my_special_method) #=> true
252
+
253
+ === Hashとお近づきに
254
+
255
+ * どちらかというとStructはHashよりArray寄りな感じを受けるのですが、個人的にHash的な動きをしてくれると嬉しい事の方が多く感じます。
256
+ ということで、やり過ぎない範囲でHashっぽく使えるように調整しています。
257
+
258
+ * Hashへの変換も一発です。
259
+ user3.to_h #=> {:lank=>3, :name=>nil}
260
+
261
+ == Note
262
+
263
+ * 現状、このReadme含めてドキュメントは殆ど更新出来ていません。
264
+
265
+ == REQUIREMENTS
266
+
267
+ === Ruby
268
+
269
+ * Ruby 1.9.2 and later (tested 1.9.2, 1.9.3)
270
+
271
+ == INSTALL
272
+
273
+ * sudo gem install striuct
274
+
275
+ == LICENSE
276
+
277
+ (The MIT License)
278
+
279
+ Copyright (c) 2011 Kenichi Kamiya
280
+
281
+ Permission is hereby granted, free of charge, to any person obtaining
282
+ a copy of this software and associated documentation files (the
283
+ 'Software'), to deal in the Software without restriction, including
284
+ without limitation the rights to use, copy, modify, merge, publish,
285
+ distribute, sublicense, and/or sell copies of the Software, and to
286
+ permit persons to whom the Software is furnished to do so, subject to
287
+ the following conditions:
288
+
289
+ The above copyright notice and this permission notice shall be
290
+ included in all copies or substantial portions of the Software.
291
+
292
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
293
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
294
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
295
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
296
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
297
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
298
298
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.