striuct 0.0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/History.rdoc +110 -0
- data/Manifest.txt +15 -0
- data/README.ja.rdoc +244 -0
- data/README.rdoc +220 -0
- data/Rakefile +22 -0
- data/example.rb +214 -0
- data/lib/striuct/classutil.rb +26 -0
- data/lib/striuct/core.rb +56 -0
- data/lib/striuct/import.rb +95 -0
- data/lib/striuct/subclass.rb +262 -0
- data/lib/striuct/subclass_eigen.rb +428 -0
- data/lib/striuct/version.rb +4 -0
- data/lib/striuct.rb +4 -0
- data/test/test_helper.rb +3 -0
- data/test/test_helper_import.rb +4 -0
- data/test/test_striuct.rb +580 -0
- data/test/test_striuct_import.rb +42 -0
- metadata +94 -0
data/.gemtest
ADDED
File without changes
|
data/History.rdoc
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
=== 0.0.11 2011-12-23
|
2
|
+
|
3
|
+
* modify
|
4
|
+
* Subclass.cname?
|
5
|
+
|
6
|
+
* add:
|
7
|
+
* inference checker
|
8
|
+
|
9
|
+
=== 0.0.10 2011-12-23
|
10
|
+
|
11
|
+
* delete
|
12
|
+
* Subclass#lock, Subclass#unlock?
|
13
|
+
|
14
|
+
* modify
|
15
|
+
* Subclass#freeze
|
16
|
+
* has_condition? -> has_conditions?
|
17
|
+
* Subclass.lock, Subclass.lock? -> .close, .closed?
|
18
|
+
|
19
|
+
* add:
|
20
|
+
* Subclass.protect_level # class macro
|
21
|
+
* Subclass#default?
|
22
|
+
|
23
|
+
=== 0.0.9 2011-12-21
|
24
|
+
|
25
|
+
* delete
|
26
|
+
* Striuct.load_pairs
|
27
|
+
* Subclass.conditions
|
28
|
+
* Subclass.procedures
|
29
|
+
* Subclass.defaults
|
30
|
+
|
31
|
+
* add:
|
32
|
+
* Striuct.define
|
33
|
+
* Subclass.lock
|
34
|
+
* Subclass.default_for
|
35
|
+
|
36
|
+
* fix:
|
37
|
+
* Subclass#inspect
|
38
|
+
* Subclass#to_s
|
39
|
+
|
40
|
+
* note:
|
41
|
+
* innner name changed "procedure" to "flavor"
|
42
|
+
|
43
|
+
=== 0.0.8 2011-12-18
|
44
|
+
|
45
|
+
* modify:
|
46
|
+
* Subclass.define
|
47
|
+
* Subclass.accept?
|
48
|
+
* functional checker's action:
|
49
|
+
Proc: context to instance
|
50
|
+
Method: === to call
|
51
|
+
|
52
|
+
* add:
|
53
|
+
* Subclass.default
|
54
|
+
|
55
|
+
* fix:
|
56
|
+
* Subclass#values_at
|
57
|
+
|
58
|
+
=== 0.0.7 2011-12-16
|
59
|
+
|
60
|
+
* modify:
|
61
|
+
* called macro's block to procedure
|
62
|
+
* public to private Subclass#unlock
|
63
|
+
|
64
|
+
* add:
|
65
|
+
* Subclass.define
|
66
|
+
* Subclass.accept?
|
67
|
+
* Subclass.restrict?
|
68
|
+
* Subclass#assign?
|
69
|
+
* Subclass#assign
|
70
|
+
|
71
|
+
* fix:
|
72
|
+
* use clone method ( initialize_copy )
|
73
|
+
|
74
|
+
=== 0.0.6 2011-12-14
|
75
|
+
|
76
|
+
* modify:
|
77
|
+
* error type in some methods
|
78
|
+
|
79
|
+
* add:
|
80
|
+
* Subclass.sufficent?
|
81
|
+
* Subclass.define
|
82
|
+
* Subclass#sufficent?
|
83
|
+
* Subclass#secure?
|
84
|
+
* Subclass#lock?
|
85
|
+
* Subclass#lock
|
86
|
+
* Subclass#unlock
|
87
|
+
|
88
|
+
* fix:
|
89
|
+
* typo
|
90
|
+
|
91
|
+
=== 0.0.5 2011-12-14
|
92
|
+
|
93
|
+
* fix class constructor
|
94
|
+
* modify #inspect
|
95
|
+
* add arguments checks
|
96
|
+
|
97
|
+
=== 0.0.4 2011-12-13
|
98
|
+
|
99
|
+
* divide modules for subclass methods
|
100
|
+
* modify return values for void methods
|
101
|
+
|
102
|
+
=== 0.0.3 2011-12-12
|
103
|
+
|
104
|
+
=== 0.0.2 2011-12-11
|
105
|
+
|
106
|
+
=== 0.0.1 2011-12-11
|
107
|
+
|
108
|
+
* 1 major enhancement:
|
109
|
+
* Initial release
|
110
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
History.rdoc
|
2
|
+
Manifest.txt
|
3
|
+
README.rdoc
|
4
|
+
README.ja.rdoc
|
5
|
+
Rakefile
|
6
|
+
example.rb
|
7
|
+
lib/striuct.rb
|
8
|
+
lib/striuct/core.rb
|
9
|
+
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
|
14
|
+
test/test_helper.rb
|
15
|
+
test/test_striuct.rb
|
data/README.ja.rdoc
ADDED
@@ -0,0 +1,244 @@
|
|
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
|
+
Strict Struct の略です。そのまま StrictStruct でも使えます。
|
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
|
+
|
23
|
+
== FEATURES
|
24
|
+
|
25
|
+
* メンバ毎に、参照条件を簡単に定義できます。
|
26
|
+
* 型チェックではなく式チェックなので、動的言語の良さを殺しません
|
27
|
+
* Proc(lambda)やMethod等 を使うことで、さらに柔軟なチェックが可能です
|
28
|
+
* どれか一つの構造体で最初に代入したオブジェクトのクラスで固定するようなメンバを作れます。
|
29
|
+
* 参照前に、ちょっとした処理を加える事も可能です
|
30
|
+
* 構造体としてのメンバ追加時、Rubyの既存メソッドと干渉しないかを指定レベル別にチェック可能です。
|
31
|
+
* Structの心地よい操作感を残したまま機能追加をしています。
|
32
|
+
* 既存クラスやメソッドの上書き等を(勝手には)しない、控えめな名前空間
|
33
|
+
* pure-ruby
|
34
|
+
|
35
|
+
== SYNOPSIS
|
36
|
+
|
37
|
+
* setup
|
38
|
+
require 'striuct'
|
39
|
+
|
40
|
+
* Structには無い機能として、memberというクラスマクロを用意しました。
|
41
|
+
ここでの定義順通りにindexが振られます。
|
42
|
+
引数1にメンバ名、引数2以降に参照条件を渡して下さい。caseのwhen節と同じ感覚で使えます。
|
43
|
+
引数1のみの場合、Structのメンバと同様ノーチェックになります。
|
44
|
+
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/
|
49
|
+
end
|
50
|
+
|
51
|
+
# これはOK
|
52
|
+
user = User.new 128381, 'Tokyo Japan', 20
|
53
|
+
|
54
|
+
# これもOK
|
55
|
+
user.age = 30
|
56
|
+
user.name = 'taro yamada'
|
57
|
+
|
58
|
+
# これは駄目(例外 Striuct::ConditionError)
|
59
|
+
user[:id] = 10.0
|
60
|
+
user[1] = 'Tokyo-to'
|
61
|
+
user.age = 19
|
62
|
+
user.name = nil
|
63
|
+
|
64
|
+
|
65
|
+
* リンク貼る時どれだけ注意しても、その後参照先のオブジェクトがぶっ壊れる可能性は残りますよね。
|
66
|
+
これは致し方無いと思うので、チェックだけでも簡単にできるようにしています。
|
67
|
+
user.strict? #=> true
|
68
|
+
user.address.clear
|
69
|
+
user.strict? #=> false
|
70
|
+
|
71
|
+
* 単純な例としてはこんな感じですが、更に細かいチェッカが必要であれば関数オブジェクトを使って下さい。
|
72
|
+
この時Proc(lambda)を構造体インスタンスのコンテキストで評価する為、他のメンバと連携したチェックも簡単です。
|
73
|
+
module Game
|
74
|
+
class Character
|
75
|
+
end
|
76
|
+
|
77
|
+
class DB < Striuct.new
|
78
|
+
member :monsters, ->monsters{(monsters - characters).empty?}
|
79
|
+
member :characters, ->characters{characters.all?{|c|c.kind_of? Character}}
|
80
|
+
end
|
81
|
+
|
82
|
+
monster = Character.new
|
83
|
+
db = DB.new
|
84
|
+
|
85
|
+
# fail
|
86
|
+
db.characters = [1, 2]
|
87
|
+
|
88
|
+
# pass
|
89
|
+
db.characters = [monster, Character.new]
|
90
|
+
|
91
|
+
# fail
|
92
|
+
db.monsters = [:dummy]
|
93
|
+
|
94
|
+
# pass
|
95
|
+
db.monsters = [monster]
|
96
|
+
end
|
97
|
+
|
98
|
+
* 構造体クラスのコンテキスト内だけで使える "inference" というメソッドの返り値を渡すと、
|
99
|
+
最初にどれか一つのインスタンスで参照したクラスが以降の参照条件となります。
|
100
|
+
class FlexibleContainer < Striuct.new
|
101
|
+
member :anything, inference
|
102
|
+
member :number, inference, Numeric
|
103
|
+
end
|
104
|
+
|
105
|
+
fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
|
106
|
+
# pass
|
107
|
+
fc1.anything = 'str'
|
108
|
+
|
109
|
+
# fail
|
110
|
+
fc1.anything = :sym
|
111
|
+
fc2.anything = :sym
|
112
|
+
|
113
|
+
# pass
|
114
|
+
fc2.anything = 'string too'
|
115
|
+
|
116
|
+
# fail
|
117
|
+
fc1.number = 'str'
|
118
|
+
|
119
|
+
# pass
|
120
|
+
fc1.number = 1.0
|
121
|
+
|
122
|
+
# fail
|
123
|
+
fc2.number = 1
|
124
|
+
|
125
|
+
|
126
|
+
* memberマクロへブロックを渡しておくと、チェック後一処理加えた値を代入可能です。
|
127
|
+
class User2 < Striuct.new
|
128
|
+
# 数字っぽければIntegerへ変換してから
|
129
|
+
member :age, /\A\d+\z/, Numeric do |v|
|
130
|
+
Integer v
|
131
|
+
end
|
132
|
+
|
133
|
+
# Symbolに変換した上で代入。
|
134
|
+
member :name, ->v{v.respond_to? :to_s} do |v|
|
135
|
+
v.to_s.to_sym
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
user2 = User2.new
|
140
|
+
user2.age = 9 #=> 9(Fixnum)
|
141
|
+
user2.age = 10.1 #=> 10(Fixnum)
|
142
|
+
user2.age = '10' #=> 10(Fixnum)
|
143
|
+
|
144
|
+
user2.name = 10 #=> :10(Symbol)
|
145
|
+
|
146
|
+
* Structだと標準値は全て nil になってしまいますが、これもクラスマクロで定義できるようにしました。
|
147
|
+
class User3 < Striuct.new
|
148
|
+
member :lank, Fixnum
|
149
|
+
default :lank, 3
|
150
|
+
member :name
|
151
|
+
end
|
152
|
+
|
153
|
+
user3 = User3.new
|
154
|
+
user3.lank #=> 3
|
155
|
+
|
156
|
+
* 「意図的にnilを定義する」事もありますよね
|
157
|
+
初期nilとの判別用メソッドを追加しました。
|
158
|
+
|
159
|
+
user3.name #=> nil
|
160
|
+
user3.assign? :name #=> false
|
161
|
+
user3.name = nil
|
162
|
+
user3.assign? :name #=> true
|
163
|
+
|
164
|
+
* Structはこんな感じで、ノーガード上書き&メソッド定義出来ない物も無警告で進みます
|
165
|
+
NoGuard = Struct.new :__send__, :'? !'
|
166
|
+
noguard = NoGuard.new false
|
167
|
+
p noguard.__send__
|
168
|
+
p noguard.methods.include?(:'? !') # lost!!
|
169
|
+
|
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__, :'? !'
|
189
|
+
end
|
190
|
+
|
191
|
+
* Structの良さは無くしたくないですよね
|
192
|
+
Sth1 = Striuct.new :id, :last_name, :family_name, :address, :age
|
193
|
+
|
194
|
+
Sth2 = Striuct.new do
|
195
|
+
def my_special_method
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
Sth2.new.respond_to?(:my_special_method) #=> true
|
200
|
+
|
201
|
+
* 混在利用させたい向きとかに、Structにも同じようなインターフェイスを用意できます。
|
202
|
+
逆に言うと、これを使わない限りは名前空間をあんまし汚しません。
|
203
|
+
require 'striuct/import'
|
204
|
+
|
205
|
+
* 他にも幾つか機能追加しています。
|
206
|
+
また、ここの例だと返り値や例外が見づらいと思うので、同梱の example.rb を動かしてみてください
|
207
|
+
|
208
|
+
* 早わかり
|
209
|
+
https://github.com/kachick/striuct/wiki/EasyGuide
|
210
|
+
|
211
|
+
== REQUIREMENTS
|
212
|
+
|
213
|
+
=== Ruby
|
214
|
+
* 1.9.3
|
215
|
+
* 1.9.2
|
216
|
+
|
217
|
+
== INSTALL
|
218
|
+
|
219
|
+
* sudo gem install striuct
|
220
|
+
|
221
|
+
== LICENSE
|
222
|
+
|
223
|
+
(The MIT License)
|
224
|
+
|
225
|
+
Copyright (c) 2011 Kenichi Kamiya
|
226
|
+
|
227
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
228
|
+
a copy of this software and associated documentation files (the
|
229
|
+
'Software'), to deal in the Software without restriction, including
|
230
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
231
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
232
|
+
permit persons to whom the Software is furnished to do so, subject to
|
233
|
+
the following conditions:
|
234
|
+
|
235
|
+
The above copyright notice and this permission notice shall be
|
236
|
+
included in all copies or substantial portions of the Software.
|
237
|
+
|
238
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
239
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
240
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
241
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
242
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
243
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
244
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,220 @@
|
|
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
|
+
Striuct means Strict Struct.
|
10
|
+
Handy and safty than Ruby's Standard Struct.
|
11
|
+
|
12
|
+
== FEATURES
|
13
|
+
* Provides automated checking for your setters.
|
14
|
+
* When you link a object, Striuct checks "They are valid objects?".
|
15
|
+
These checkers are not only Type Checker. They judge under your expressions.
|
16
|
+
* when use "inference", member will be fixed first passed object's class
|
17
|
+
* After check, you can add one-step before link a object (call "flavor" at here).
|
18
|
+
* You will be set default-value, and we have different meanings between nil and default-value.
|
19
|
+
* without undesirable naming for conflict, no-identifier, and more cases
|
20
|
+
* Base API looks like Ruby's standard Struct
|
21
|
+
* not taint your name-space(exclude striuct/import)
|
22
|
+
* pure-ruby
|
23
|
+
|
24
|
+
== SYNOPSIS
|
25
|
+
|
26
|
+
* setup
|
27
|
+
require 'striuct'
|
28
|
+
|
29
|
+
* Macro "member" provides one of Struct+ interface.
|
30
|
+
It checks under conditions when change to link other.
|
31
|
+
class User < Striuct.new
|
32
|
+
member :id, Integer
|
33
|
+
member :address, /\A((\w+) ?)+\z/
|
34
|
+
member :age, (20..140)
|
35
|
+
member :name, /\A\w+\z/, /\A\w+ \w+\z/
|
36
|
+
end
|
37
|
+
|
38
|
+
# pass
|
39
|
+
user = User.new 128381, 'Tokyo Japan', 20
|
40
|
+
|
41
|
+
# pass
|
42
|
+
user.age = 30
|
43
|
+
user.name = 'taro yamada'
|
44
|
+
|
45
|
+
# fail
|
46
|
+
user[:id] = 10.0
|
47
|
+
user[1] = 'Tokyo-to'
|
48
|
+
user.age = 19
|
49
|
+
user.name = nil
|
50
|
+
|
51
|
+
* more detail checker do you need, you can use functional object here.
|
52
|
+
module Game
|
53
|
+
class Character
|
54
|
+
end
|
55
|
+
|
56
|
+
class DB < Striuct.new
|
57
|
+
member :monsters, ->monsters{(monsters - characters).empty?}
|
58
|
+
member :characters, ->characters{characters.all?{|c|c.kind_of? Character}}
|
59
|
+
end
|
60
|
+
|
61
|
+
monster = Character.new
|
62
|
+
db = DB.new
|
63
|
+
|
64
|
+
# fail
|
65
|
+
db.characters = [1, 2]
|
66
|
+
|
67
|
+
# pass
|
68
|
+
db.characters = [monster, Character.new]
|
69
|
+
|
70
|
+
# fail
|
71
|
+
db.monsters = [:dummy]
|
72
|
+
|
73
|
+
# pass
|
74
|
+
db.monsters = [monster]
|
75
|
+
end
|
76
|
+
|
77
|
+
* "inference", check under first passed object's class
|
78
|
+
class FlexibleContainer < Striuct.new
|
79
|
+
member :anything, inference
|
80
|
+
member :number, inference, Numeric
|
81
|
+
end
|
82
|
+
|
83
|
+
fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
|
84
|
+
# pass
|
85
|
+
fc1.anything = 'str'
|
86
|
+
|
87
|
+
# fail
|
88
|
+
fc1.anything = :sym
|
89
|
+
fc2.anything = :sym
|
90
|
+
|
91
|
+
# pass
|
92
|
+
fc2.anything = 'string too'
|
93
|
+
|
94
|
+
# fail
|
95
|
+
fc1.number = 'str'
|
96
|
+
|
97
|
+
# pass
|
98
|
+
fc1.number = 1.0
|
99
|
+
|
100
|
+
# fail
|
101
|
+
fc2.number = 1
|
102
|
+
|
103
|
+
* with flavor for type cast
|
104
|
+
class User2 < Striuct.new
|
105
|
+
member :age, /\A\d+\z/, Numeric do |arg|
|
106
|
+
Integer arg
|
107
|
+
end
|
108
|
+
|
109
|
+
member :name, ->v{v.respond_to? :to_s} do |v|
|
110
|
+
v.to_s.to_sym
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
user2 = User2.new
|
115
|
+
user2.age = 9 #=> 9(Fixnum)
|
116
|
+
user2.age = 10.1 #=> 10(Fixnum)
|
117
|
+
user2.age = '10' #=> 10(Fixnum)
|
118
|
+
|
119
|
+
user2.name = 10 #=> :10(Symbol)
|
120
|
+
|
121
|
+
* but, linked objects are able to clash
|
122
|
+
user.strict? #=> true
|
123
|
+
user.address.clear
|
124
|
+
user.strict? #=> false
|
125
|
+
|
126
|
+
* use default value
|
127
|
+
class User3 < Striuct.new
|
128
|
+
member :lank, Fixnum
|
129
|
+
default :lank, 3
|
130
|
+
member :name
|
131
|
+
end
|
132
|
+
|
133
|
+
user3 = User3.new
|
134
|
+
user3.lank #=> 3
|
135
|
+
|
136
|
+
* Standard Struct always define "nil is default". ...realy?
|
137
|
+
user3.name #=> nil
|
138
|
+
user3.assign? :name #=> false
|
139
|
+
user3.name = nil
|
140
|
+
user3.assign? :name #=> true
|
141
|
+
|
142
|
+
* Standard Struct no check member name.
|
143
|
+
NoGuard = Struct.new :__send__, :'? !'
|
144
|
+
noguard = NoGuard.new false
|
145
|
+
p noguard.__send__
|
146
|
+
p noguard.methods.include?(:'? !') # lost!!
|
147
|
+
|
148
|
+
* Striuct provides safety levels for naming.
|
149
|
+
class SafetyNaming < Striuct.new
|
150
|
+
begin
|
151
|
+
member :__send__
|
152
|
+
rescue
|
153
|
+
p $!
|
154
|
+
end
|
155
|
+
|
156
|
+
begin
|
157
|
+
member :'? !'
|
158
|
+
rescue
|
159
|
+
p $!
|
160
|
+
end
|
161
|
+
|
162
|
+
protect_level :struct
|
163
|
+
|
164
|
+
member :__send__, :'? !'
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
* Of course, keeping Struct's good interface
|
169
|
+
Sth1 = Striuct.new :id, :last_name, :family_name, :address, :age
|
170
|
+
|
171
|
+
Sth2 = Striuct.new do
|
172
|
+
def my_special_method
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
Sth2.new.respond_to?(:my_special_method) #=> true
|
177
|
+
|
178
|
+
* Here, not taint your name-space. but enhancers are too, you can choose it.
|
179
|
+
require 'striuct/import'
|
180
|
+
|
181
|
+
* run example.rb
|
182
|
+
|
183
|
+
* EasyGuide (in Japanese)
|
184
|
+
https://github.com/kachick/striuct/wiki/EasyGuide
|
185
|
+
|
186
|
+
|
187
|
+
== REQUIREMENTS
|
188
|
+
|
189
|
+
=== Ruby
|
190
|
+
* 1.9.3
|
191
|
+
* 1.9.2
|
192
|
+
|
193
|
+
== INSTALL
|
194
|
+
|
195
|
+
* sudo gem install striuct
|
196
|
+
|
197
|
+
== LICENSE
|
198
|
+
|
199
|
+
(The MIT License)
|
200
|
+
|
201
|
+
Copyright (c) 2011 Kenichi Kamiya
|
202
|
+
|
203
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
204
|
+
a copy of this software and associated documentation files (the
|
205
|
+
'Software'), to deal in the Software without restriction, including
|
206
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
207
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
208
|
+
permit persons to whom the Software is furnished to do so, subject to
|
209
|
+
the following conditions:
|
210
|
+
|
211
|
+
The above copyright notice and this permission notice shall be
|
212
|
+
included in all copies or substantial portions of the Software.
|
213
|
+
|
214
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
215
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
216
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
217
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
218
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
219
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
220
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.12.4'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
Hoe.plugin :newgem
|
7
|
+
# Hoe.plugin :website
|
8
|
+
# Hoe.plugin :cucumberfeatures
|
9
|
+
|
10
|
+
# Generate all the Rake tasks
|
11
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
12
|
+
$hoe = Hoe.spec 'striuct' do
|
13
|
+
self.developer 'Kenichi Kamiya', 'kachick1+ruby@gmail.com'
|
14
|
+
self.rubyforge_name = self.name # TODO this is default value
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'newgem/tasks'
|
18
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
19
|
+
|
20
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
21
|
+
# remove_task :default
|
22
|
+
# task :default => [:spec, :features]
|