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 CHANGED
@@ -1,41 +1,134 @@
1
+ === 0.1.7 2012-1-26
2
+
3
+ * add:
4
+ * default with Proc
5
+ * detail error message in Subclass.#[]=
6
+
7
+ * fix
8
+ * class duplicating
9
+
10
+ === 0.1.6 2012-1-25
11
+
12
+ * delete:
13
+ * import.rb
14
+
15
+ * modify:
16
+ * Subclass.#define
17
+ * naming risks (add bad name "_foo")
18
+ * Conditions.#GENERICS (enum prior all? to each_value.all?)
19
+ * timing of check default value
20
+
21
+ * add:
22
+ * detail error message in Subclass.#define
23
+
24
+ * fix:
25
+ * inherited behavior
26
+
27
+ === 0.1.5 2012-1-17
28
+
29
+ * add:
30
+ * #lock, #lock?
31
+ * some Specific Conditions
32
+
33
+ * note:
34
+ multiple conditions for 'or', dupulicated for direct throw member macro
35
+ please use .#OR method in this case
36
+
37
+ === 0.1.4 2012-1-16
38
+
39
+ * modify:
40
+ * trace logs
41
+ * naming risks(add bad name "to_foo")
42
+ * Subclass#unassign
43
+
44
+ * add:
45
+ * Specific Conditions
46
+ (for Syntax Sugar of useful Functional Conditions)
47
+ * Subclass.#each_index
48
+ * Subclass.#valid?
49
+ * Subclass#clear_at, reset_at
50
+
51
+ === 0.1.3 2012-1-10
52
+
53
+ * add:
54
+ * Subclass.#alias_member
55
+ * Subclass.#valid?
56
+ * Subclass#valid?
57
+
58
+ === 0.1.2 2012-1-9
59
+
60
+ * modify:
61
+ * Subclass.#hash
62
+
63
+ * add:
64
+ * Subclass.#to_yaml
65
+
66
+ === 0.1.1 2011-12-26
67
+
68
+ * modify:
69
+ * Subclass.#sufficient?
70
+
71
+ * add:
72
+ * Subclass.#empty?
73
+ * Subclass.#has_value? (value?)
74
+ * Subclass.#flatten
75
+ * Subclass.#select! (keep_if)
76
+ * Subclass.#select
77
+ * Subclass.#reject! (delete_if)
78
+ * Subclass.#reject
79
+ * Subclass.#assoc
80
+ * Subclass.#rassoc
81
+
82
+ * fix
83
+ * Subclass.#sufficient?
84
+
85
+ === 0.1.0 2011-12-25
86
+
87
+ * modify:
88
+ * Subclass.#define
89
+
90
+ * add:
91
+ * Subclass.#[] (alias load_pairs)
92
+ * Subclass.#to_h
93
+
1
94
  === 0.0.11 2011-12-23
2
95
 
3
- * modify
4
- * Subclass.cname?
96
+ * modify:
97
+ * Subclass.#cname?
5
98
 
6
99
  * add:
7
100
  * inference checker
8
101
 
9
102
  === 0.0.10 2011-12-23
10
103
 
11
- * delete
12
- * Subclass#lock, Subclass#unlock?
104
+ * delete:
105
+ * Subclass.#lock, Subclass.#unlock?
13
106
 
14
- * modify
15
- * Subclass#freeze
107
+ * modify:
108
+ * Subclass.#freeze
16
109
  * has_condition? -> has_conditions?
17
- * Subclass.lock, Subclass.lock? -> .close, .closed?
110
+ * Subclass.#lock, Subclass.#lock? -> .close, .closed?
18
111
 
19
112
  * add:
20
- * Subclass.protect_level # class macro
21
- * Subclass#default?
113
+ * Subclass.#protect_level # class macro
114
+ * Subclass.#default?
22
115
 
23
116
  === 0.0.9 2011-12-21
24
117
 
25
- * delete
118
+ * delete:
26
119
  * Striuct.load_pairs
27
- * Subclass.conditions
28
- * Subclass.procedures
29
- * Subclass.defaults
120
+ * Subclass.#conditions
121
+ * Subclass.#procedures
122
+ * Subclass.#defaults
30
123
 
31
124
  * add:
32
125
  * Striuct.define
33
- * Subclass.lock
34
- * Subclass.default_for
126
+ * Subclass.#lock
127
+ * Subclass.#default_for
35
128
 
36
129
  * fix:
37
- * Subclass#inspect
38
- * Subclass#to_s
130
+ * Subclass.#inspect
131
+ * Subclass.#to_s
39
132
 
40
133
  * note:
41
134
  * innner name changed "procedure" to "flavor"
@@ -43,30 +136,30 @@
43
136
  === 0.0.8 2011-12-18
44
137
 
45
138
  * modify:
46
- * Subclass.define
47
- * Subclass.accept?
139
+ * Subclass.#define
140
+ * Subclass.#accept?
48
141
  * functional checker's action:
49
142
  Proc: context to instance
50
143
  Method: === to call
51
144
 
52
145
  * add:
53
- * Subclass.default
146
+ * Subclass.#default
54
147
 
55
148
  * fix:
56
- * Subclass#values_at
149
+ * Subclass.#values_at
57
150
 
58
151
  === 0.0.7 2011-12-16
59
152
 
60
153
  * modify:
61
154
  * called macro's block to procedure
62
- * public to private Subclass#unlock
155
+ * public to private Subclass.#unlock
63
156
 
64
157
  * add:
65
- * Subclass.define
66
- * Subclass.accept?
67
- * Subclass.restrict?
68
- * Subclass#assign?
69
- * Subclass#assign
158
+ * Subclass.#define
159
+ * Subclass.#accept?
160
+ * Subclass.#restrict?
161
+ * Subclass.#assign?
162
+ * Subclass.#assign
70
163
 
71
164
  * fix:
72
165
  * use clone method ( initialize_copy )
@@ -77,13 +170,13 @@
77
170
  * error type in some methods
78
171
 
79
172
  * add:
80
- * Subclass.sufficent?
81
- * Subclass.define
82
- * Subclass#sufficent?
83
- * Subclass#secure?
84
- * Subclass#lock?
85
- * Subclass#lock
86
- * Subclass#unlock
173
+ * Subclass.#sufficent?
174
+ * Subclass.#define
175
+ * Subclass.#sufficent?
176
+ * Subclass.#secure?
177
+ * Subclass.#lock?
178
+ * Subclass.#lock
179
+ * Subclass.#unlock
87
180
 
88
181
  * fix:
89
182
  * typo
@@ -96,7 +189,7 @@
96
189
 
97
190
  === 0.0.4 2011-12-13
98
191
 
99
- * divide modules for subclass methods
192
+ * divide modules for Subclass.#methods
100
193
  * modify return values for void methods
101
194
 
102
195
  === 0.0.3 2011-12-12
data/Manifest.txt CHANGED
@@ -3,13 +3,28 @@ Manifest.txt
3
3
  README.rdoc
4
4
  README.ja.rdoc
5
5
  Rakefile
6
- example.rb
7
6
  lib/striuct.rb
8
- lib/striuct/core.rb
7
+ lib/striuct/frame.rb
9
8
  lib/striuct/version.rb
10
- lib/striuct/classutil.rb
11
- lib/striuct/subclass.rb
12
- lib/striuct/subclass_eigen.rb
13
- lib/striuct/import.rb
9
+ lib/striuct/abstract.rb
10
+ lib/striuct/conditions.rb
11
+ lib/striuct/subclassable/frame.rb
12
+ lib/striuct/subclassable/classutil.rb
13
+ lib/striuct/subclassable/basic.rb
14
+ lib/striuct/subclassable/safety.rb
15
+ lib/striuct/subclassable/handy.rb
16
+ lib/striuct/subclassable/hashlike.rb
17
+ lib/striuct/subclassable/yaml.rb
18
+ lib/striuct/subclassable/inner.rb
19
+ lib/striuct/subclassable/eigen/frame.rb
20
+ lib/striuct/subclassable/eigen/basic.rb
21
+ lib/striuct/subclassable/eigen/constructor.rb
22
+ lib/striuct/subclassable/eigen/safety.rb
23
+ lib/striuct/subclassable/eigen/handy.rb
24
+ lib/striuct/subclassable/eigen/macro.rb
25
+ lib/striuct/subclassable/eigen/inner.rb
14
26
  test/test_helper.rb
15
27
  test/test_striuct.rb
28
+ example/example.rb
29
+ example/benchmarks.rb
30
+ example/see_trace.rb
data/README.ja.rdoc CHANGED
@@ -6,79 +6,82 @@
6
6
 
7
7
  == DESCRIPTION
8
8
 
9
- Strict Struct の略です。そのまま StrictStruct でも使えます。
9
+ Struct以上の手軽さで扱える、Structより堅いコンテナを目指しています。
10
10
 
11
- メンバ名チェックのかかるStructは、安心感という意味ではHashよりも好ましい事があるかと思います。
12
- でもそうやってStructを使うぐらいなわけだから、名前だけじゃなく参照先にもある程度の代入条件をかけたいと思う事が多くありませんか?
11
+ メンバ名にチェックがかかる&一つの新しいクラスとして扱えるStructは、場面によってはHashよりも好ましい事があるかと思います。
12
+ でもそうやってStructを使うぐらいなわけだから、値の方にもある程度のチェックをかけたいと思う事が多くありませんか?
13
13
 
14
14
  RubyのStructを愛しつつも、こういった部分をなんとかしたいと感じている方へお勧めします。
15
15
 
16
16
  1. ノーガードで参照を付けられるのがおっかないときもある
17
17
  2. かといって、型チェックしか出来ないようじゃRubyのメリットが死ぬんではなかろうか
18
18
  3. メンバ名でフツーのメソッド名を上書きしかねないのもおっかない
19
- 4. 最初に代入したオブジェクトのクラスで固定したい
20
- 5. どうせなら、チェックだけじゃなくキャストなりもやらせたものを参照したい
19
+ 4. 最初に代入したオブジェクトのクラスで固定したい(これは無いか)
20
+ 5. どうせなら、チェックだけじゃなくキャストなりやらせたものを参照したい
21
21
  6. メンバによっては標準値も定義したい
22
+ 7. Hashとの親和性を高くしたい
23
+ 8. メンバ名にaliasかけたいけど、alias_methodだけだと添え字アクセス出来なくて歯がゆい
24
+ 9. 構造体クラスでも継承を使った上で、更にメンバ追加がしたい
22
25
 
23
26
  == FEATURES
24
27
 
25
28
  * メンバ毎に、参照条件を簡単に定義できます。
26
- * 型チェックではなく式チェックなので、動的言語の良さを殺しません
29
+ * 型チェックではなく式チェックなので、動的型の良さを殺しません
27
30
  * Proc(lambda)やMethod等 を使うことで、さらに柔軟なチェックが可能です
28
- * どれか一つの構造体で最初に代入したオブジェクトのクラスで固定するようなメンバを作れます。
29
- * 参照前に、ちょっとした処理を加える事も可能です
30
- * 構造体としてのメンバ追加時、Rubyの既存メソッドと干渉しないかを指定レベル別にチェック可能です。
31
- * Structの心地よい操作感を残したまま機能追加をしています。
31
+ * どれか一つの構造体で最初に代入したオブジェクトのクラスに沿うようなメンバを作れます。
32
+ * 参照直前に、ちょっとした処理を加える事も可能です
33
+ * 構造体としてのメンバ追加時、Rubyの既存メソッドと干渉しないかを指定レベル別にチェック出来ます。
34
+ * 違和感のない継承利用
35
+ * なるべくStructの心地よい操作感を残したまま機能追加をしています。
32
36
  * 既存クラスやメソッドの上書き等を(勝手には)しない、控えめな名前空間
33
- * pure-ruby
37
+ * Pure Ruby
34
38
 
35
39
  == SYNOPSIS
36
40
 
37
41
  * setup
38
42
  require 'striuct'
39
43
 
40
- * Structには無い機能として、memberというクラスマクロを用意しました。
41
- ここでの定義順通りにindexが振られます。
42
- 引数1にメンバ名、引数2以降に参照条件を渡して下さい。caseのwhen節と同じ感覚で使えます。
43
- 引数1のみの場合、Structのメンバと同様ノーチェックになります。
44
+ * 2つの名前空間をお借りしますが、どっちも同じクラスを指します
45
+ Striuct
46
+ StrictStruct
47
+
48
+ === Struct+ "Safety"
49
+
50
+ ==== 基本的な使い方
51
+
52
+ * memberというクラスマクロを使うことで構造体のメンバを定義できます。
53
+ 引数2以降に、参照するための「条件」を渡して下さい。
54
+ 何も条件を渡さなければ、Struct同様ノーチェックです。
44
55
  class User < Striuct.new
45
- member :id, Integer
46
- member :address, /\A((\w+) ?)+\z/
47
- member :age, (20..140)
48
- member :name, /\A\w+\z/, /\A\w+ \w+\z/
56
+ member :id, Integer
57
+ member :age, (20..140)
58
+ member :name, OR(/\A\w+\z/, /\A\w+ \w+\z/)
49
59
  end
50
60
 
51
- # これはOK
52
- user = User.new 128381, 'Tokyo Japan', 20
61
+ # pass
62
+ user = User.new 128381, 20
53
63
 
54
- # これもOK
64
+ # pass
55
65
  user.age = 30
56
- user.name = 'taro yamada'
66
+ user[2] = 'taro yamada'
57
67
 
58
- # これは駄目(例外 Striuct::ConditionError)
68
+ # fail
59
69
  user[:id] = 10.0
60
- user[1] = 'Tokyo-to'
61
70
  user.age = 19
62
- user.name = nil
71
+ user[2] = nil
63
72
 
64
-
65
- * リンク貼る時どれだけ注意しても、その後参照先のオブジェクトがぶっ壊れる可能性は残りますよね。
66
- これは致し方無いと思うので、チェックだけでも簡単にできるようにしています。
67
- user.strict? #=> true
68
- user.address.clear
69
- user.strict? #=> false
70
73
 
71
- * 単純な例としてはこんな感じですが、更に細かいチェッカが必要であれば関数オブジェクトを使って下さい。
74
+ * 更に柔軟なチェッカが必要であれば関数的なオブジェクトを使って下さい。
72
75
  この時Proc(lambda)を構造体インスタンスのコンテキストで評価する為、他のメンバと連携したチェックも簡単です。
73
76
  module Game
74
77
  class Character
75
78
  end
76
79
 
77
80
  class DB < Striuct.new
78
- member :monsters, ->monsters{(monsters - characters).empty?}
79
- member :characters, ->characters{characters.all?{|c|c.kind_of? Character}}
81
+ member :monsters, ->list{(list - characters).empty?}
82
+ member :characters, GENERICS(Character)
80
83
  end
81
-
84
+
82
85
  monster = Character.new
83
86
  db = DB.new
84
87
 
@@ -89,17 +92,17 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい
89
92
  db.characters = [monster, Character.new]
90
93
 
91
94
  # fail
92
- db.monsters = [:dummy]
95
+ db.monsters = [:Character.new]
93
96
 
94
97
  # pass
95
98
  db.monsters = [monster]
96
99
  end
97
100
 
98
101
  * 構造体クラスのコンテキスト内だけで使える "inference" というメソッドの返り値を渡すと、
99
- 最初にどれか一つのインスタンスで参照したクラスが以降の参照条件となります。
102
+ 最初に参照したオブジェクトのクラスが、以降全インスタンスでの参照条件となります。
100
103
  class FlexibleContainer < Striuct.new
101
104
  member :anything, inference
102
- member :number, inference, Numeric
105
+ member :number, Numeric, inference
103
106
  end
104
107
 
105
108
  fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
@@ -122,8 +125,51 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい
122
125
  # fail
123
126
  fc2.number = 1
124
127
 
128
+ ==== 意図しない名前干渉は避ける
129
+
130
+ * Structはこんな感じで、ノーガード上書き&メソッド定義出来ない物も無警告で進みます(object_id, __id__ なんかもそうですね)
131
+ NoGuard = Struct.new :__send__, :'? !'
132
+ noguard = NoGuard.new false
133
+ p noguard.__send__
134
+ p noguard.methods.include?(:'? !') # lost!!
135
+
136
+ * ということで、意図しない上書き等を防ぐために安全度を設定出来るようにしました。
137
+ 標準値は上から2番目の「:prevent」です。
138
+ class SafetyNaming < Striuct.new
139
+ begin
140
+ member :__send__
141
+ rescue
142
+ p $!
143
+ end
144
+
145
+ begin
146
+ member :'? !'
147
+ rescue
148
+ p $!
149
+ end
150
+
151
+ # ここで下げると、定義可能に
152
+ protect_level :struct
153
+
154
+ member :__send__, :'? !'
155
+ end
156
+
157
+ ==== この辺に関わる述語メソッド
158
+
159
+ * valid? / acccept? / sufficient? # そのメンバにその値が設定出来るか
160
+ * conditionable? # 条件式として受け入れ可能なオブジェクトか
161
+ * inference? # 定義時にinferenceを使った上で、一つも参照されていないか
162
+ * restrict? # そのメンバに参照条件がかけられているか
163
+ * strict? # 今時点で全てのメンバが参照条件を満たしているか
164
+ * secure? # インスタンスもクラスも変動することない状態で、インスタンスにfreezeがかかっているか
165
+ * cname? # そのメンバ名は、今のprotect level下で望ましいものか
166
+
125
167
 
126
- * memberマクロへブロックを渡しておくと、チェック後一処理加えた値を代入可能です。
168
+ === Struct+ "Handy"
169
+
170
+ ==== Flavor
171
+
172
+ * memberマクロへブロックを渡しておくと、チェック後一処理加えた値を参照可能です。
127
173
  class User2 < Striuct.new
128
174
  # 数字っぽければIntegerへ変換してから
129
175
  member :age, /\A\d+\z/, Numeric do |v|
@@ -142,8 +188,11 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい
142
188
  user2.age = '10' #=> 10(Fixnum)
143
189
 
144
190
  user2.name = 10 #=> :10(Symbol)
191
+ user2.name = Class #=> :Class(Symbol)
192
+
193
+ ==== Default
145
194
 
146
- * Structだと標準値は全て nil になってしまいますが、これもクラスマクロで定義できるようにしました。
195
+ * defaultマクロを用いることで、メンバ毎に標準値を定義することが出来ます。
147
196
  class User3 < Striuct.new
148
197
  member :lank, Fixnum
149
198
  default :lank, 3
@@ -153,44 +202,51 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい
153
202
  user3 = User3.new
154
203
  user3.lank #=> 3
155
204
 
156
- * 「意図的にnilを定義する」事もありますよね
157
- 初期nilとの判別用メソッドを追加しました。
158
-
159
- user3.name #=> nil
160
- user3.assign? :name #=> false
161
- user3.name = nil
162
- user3.assign? :name #=> true
205
+ * 「意図的なnil」との区別を付けられます。
206
+ user3.name #=> nil
207
+ user3.assign? :name #=> false
208
+ user3.name = nil
209
+ user3.assign? :name #=> true
163
210
 
164
- * Structはこんな感じで、ノーガード上書き&メソッド定義出来ない物も無警告で進みます
165
- NoGuard = Struct.new :__send__, :'? !'
166
- noguard = NoGuard.new false
167
- p noguard.__send__
168
- p noguard.methods.include?(:'? !') # lost!!
211
+ ==== Alias
169
212
 
170
- * ということで、意図しない上書き等を防ぐために安全度を設定出来るようにしました。
171
- 標準値は上から2番目です。
172
- class SafetyNaming < Striuct.new
173
- begin
174
- member :__send__
175
- rescue
176
- p $!
177
- end
178
-
179
- begin
180
- member :'? !'
181
- rescue
182
- p $!
183
- end
184
-
185
- # ここで下げると、定義可能に
186
- protect_level :struct
187
-
188
- member :__send__, :'? !'
213
+ * メンバ名を付与出来ます。(標準Structだと、添字アクセス可能にしたりするのが面倒。)
214
+ class User3
215
+ alias_member :position, :lank
189
216
  end
217
+
218
+ user3.lank.equal? user3.position #=> true
219
+ user3[:lank].equal? user3[:position] #=> true
220
+ user3[:position] = 4
221
+ user3.lank #=> 4
222
+
223
+ ==== Inherit
224
+
225
+ * (writing...)
190
226
 
191
- * Structの良さは無くしたくないですよね
192
- Sth1 = Striuct.new :id, :last_name, :family_name, :address, :age
227
+ ==== Lock
193
228
 
229
+ * (writing...)
230
+
231
+ ==== New Constructors
232
+
233
+ * Subclass.define は、生成時から先オブジェクトを変える必要が無いケースで使います。
234
+ * ブロックパラメータに新しいインスタンスがわたり、またこれが返り値となります
235
+ * すべてのメンバがアサイン済みかをチェックします
236
+ * ブロックを抜ける直前に、全て問題ない値かチェックします(オプション指定可)
237
+ * ブロックを抜ける直前に、全てlockをかけます(オプション指定可)
238
+ user3 = User3.define do |r|
239
+ r.lank = 10
240
+ r.name = 'foo'
241
+ end
242
+
243
+ * Subclass.[](load_pairs) は、HashなりHashっぽいものから作る時用です。
244
+ # Struct.[] の仕様とは異なります。
245
+ user3 = User3[lank:10, name: 'foo']
246
+
247
+ === Structの良さは活かしたまま
248
+
249
+ * 基本的にはStruct使い(?)が余り違和感を感じ無いようにしたつもりです。
194
250
  Sth2 = Striuct.new do
195
251
  def my_special_method
196
252
  end
@@ -198,21 +254,24 @@ RubyのStructを愛しつつも、こういった部分をなんとかしたい
198
254
 
199
255
  Sth2.new.respond_to?(:my_special_method) #=> true
200
256
 
201
- * 混在利用させたい向きとかに、Structにも同じようなインターフェイスを用意できます。
202
- 逆に言うと、これを使わない限りは名前空間をあんまし汚しません。
203
- require 'striuct/import'
257
+ === Hashとお近づきに
258
+
259
+ * どちらかというとStructはHashよりArray寄りな感じを受けるのですが、個人的にHash的な動きをしてくれると嬉しい事の方が多く感じます。
260
+ ということで、やり過ぎない範囲でHashっぽく使えるように調整しています。
204
261
 
205
- * 他にも幾つか機能追加しています。
206
- また、ここの例だと返り値や例外が見づらいと思うので、同梱の example.rb を動かしてみてください
262
+ * Hashへの変換も一発です。
263
+ user3.to_h #=> {:lank=>3, :name=>nil}
207
264
 
208
- * 早わかり
209
- https://github.com/kachick/striuct/wiki/EasyGuide
265
+ == Note
266
+
267
+ * 現状、このReadme含めてドキュメントは殆ど更新出来ていません。
268
+ 0.2.0 までにはなんとかしたい
210
269
 
211
270
  == REQUIREMENTS
212
271
 
213
272
  === Ruby
214
- * 1.9.3
215
- * 1.9.2
273
+
274
+ * Ruby 1.9.2 and later (tested 1.9.2, 1.9.3)
216
275
 
217
276
  == INSTALL
218
277