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 +128 -35
- data/Manifest.txt +21 -6
- data/README.ja.rdoc +142 -83
- data/README.rdoc +130 -73
- data/Rakefile +5 -3
- data/example/benchmarks.rb +56 -0
- data/{example.rb → example/example.rb} +81 -70
- data/example/see_trace.rb +28 -0
- data/lib/striuct/abstract.rb +74 -0
- data/lib/striuct/conditions.rb +228 -0
- data/lib/striuct/frame.rb +8 -0
- data/lib/striuct/subclassable/basic.rb +135 -0
- data/lib/striuct/{classutil.rb → subclassable/classutil.rb} +5 -5
- data/lib/striuct/subclassable/eigen/basic.rb +38 -0
- data/lib/striuct/subclassable/eigen/constructor.rb +58 -0
- data/lib/striuct/subclassable/eigen/frame.rb +39 -0
- data/lib/striuct/subclassable/eigen/handy.rb +92 -0
- data/lib/striuct/subclassable/eigen/inner.rb +224 -0
- data/lib/striuct/subclassable/eigen/macro.rb +108 -0
- data/lib/striuct/subclassable/eigen/safety.rb +56 -0
- data/lib/striuct/subclassable/frame.rb +33 -0
- data/lib/striuct/subclassable/handy.rb +57 -0
- data/lib/striuct/subclassable/hashlike.rb +133 -0
- data/lib/striuct/subclassable/inner.rb +108 -0
- data/lib/striuct/subclassable/safety.rb +72 -0
- data/lib/striuct/subclassable/yaml.rb +14 -0
- data/lib/striuct/version.rb +2 -2
- data/lib/striuct.rb +3 -2
- data/test/test_striuct.rb +649 -20
- metadata +55 -24
- data/lib/striuct/core.rb +0 -56
- data/lib/striuct/import.rb +0 -95
- data/lib/striuct/subclass.rb +0 -262
- data/lib/striuct/subclass_eigen.rb +0 -428
- data/test/test_helper_import.rb +0 -4
- data/test/test_striuct_import.rb +0 -42
data/README.rdoc
CHANGED
@@ -6,56 +6,63 @@
|
|
6
6
|
|
7
7
|
== DESCRIPTION
|
8
8
|
|
9
|
-
Striuct
|
10
|
-
Handy and safty than Ruby's Standard Struct.
|
9
|
+
Striuct = (YetAnotherStruct << safety << useful)
|
11
10
|
|
12
11
|
== FEATURES
|
13
|
-
* Provides automated checking for your setters.
|
14
12
|
* When you link a object, Striuct checks "They are valid objects?".
|
15
|
-
These checkers
|
16
|
-
|
17
|
-
|
18
|
-
*
|
19
|
-
* without undesirable naming
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
13
|
+
These checkers don't depend only types(class).
|
14
|
+
|
15
|
+
The safety is made from your expressions.
|
16
|
+
* When use "inference", member will be fixed under class of first passed object.
|
17
|
+
* It is without undesirable naming of conflict, no-identifier and some cases.
|
18
|
+
* You can add a step just before link a object. (named "flavor" at here)
|
19
|
+
* You can use default-value, and we have different meanings between nil and default-value.
|
20
|
+
* It is easy to alias member name.
|
21
|
+
* You can use inherite of structual class.
|
22
|
+
* Base API looks like Struct.
|
23
|
+
* No taint your name-space.
|
24
|
+
* Pure Ruby
|
23
25
|
|
24
26
|
== SYNOPSIS
|
25
27
|
|
26
28
|
* setup
|
27
29
|
require 'striuct'
|
28
30
|
|
29
|
-
*
|
30
|
-
|
31
|
+
* use two namespace (same meanings)
|
32
|
+
Striuct
|
33
|
+
StrictStruct
|
34
|
+
|
35
|
+
=== Struct+ "Safety"
|
36
|
+
|
37
|
+
==== "member" macro
|
38
|
+
|
39
|
+
* Use "member" and you get a accessor, it looks Struct with tester(validator)s.
|
31
40
|
class User < Striuct.new
|
32
|
-
member :id,
|
33
|
-
member :
|
34
|
-
member :
|
35
|
-
member :name, /\A\w+\z/, /\A\w+ \w+\z/
|
41
|
+
member :id, Integer
|
42
|
+
member :age, (20..140)
|
43
|
+
member :name, OR(/\A\w+\z/, /\A\w+ \w+\z/)
|
36
44
|
end
|
37
45
|
|
38
46
|
# pass
|
39
|
-
user = User.new 128381,
|
47
|
+
user = User.new 128381, 20
|
40
48
|
|
41
49
|
# pass
|
42
50
|
user.age = 30
|
43
|
-
user
|
51
|
+
user[2] = 'foo bar'
|
44
52
|
|
45
53
|
# fail
|
46
54
|
user[:id] = 10.0
|
47
|
-
user[1] = 'Tokyo-to'
|
48
55
|
user.age = 19
|
49
|
-
user
|
56
|
+
user[2] = nil
|
50
57
|
|
51
|
-
*
|
58
|
+
* Use functional object and you get a tester on upstairs.
|
52
59
|
module Game
|
53
60
|
class Character
|
54
61
|
end
|
55
62
|
|
56
63
|
class DB < Striuct.new
|
57
|
-
member :monsters,
|
58
|
-
member :characters,
|
64
|
+
member :monsters, ->list{(list - characters).empty?}
|
65
|
+
member :characters, GENERICS(Character)
|
59
66
|
end
|
60
67
|
|
61
68
|
monster = Character.new
|
@@ -68,16 +75,16 @@ Handy and safty than Ruby's Standard Struct.
|
|
68
75
|
db.characters = [monster, Character.new]
|
69
76
|
|
70
77
|
# fail
|
71
|
-
db.monsters = [
|
78
|
+
db.monsters = [Character.new]
|
72
79
|
|
73
80
|
# pass
|
74
81
|
db.monsters = [monster]
|
75
82
|
end
|
76
83
|
|
77
|
-
* "inference"
|
84
|
+
* Use "inference" and all instance test under class of first passed object.
|
78
85
|
class FlexibleContainer < Striuct.new
|
79
86
|
member :anything, inference
|
80
|
-
member :number,
|
87
|
+
member :number, Numeric, inference
|
81
88
|
end
|
82
89
|
|
83
90
|
fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
|
@@ -100,7 +107,50 @@ Handy and safty than Ruby's Standard Struct.
|
|
100
107
|
# fail
|
101
108
|
fc2.number = 1
|
102
109
|
|
103
|
-
|
110
|
+
==== Protect from risks in naming members
|
111
|
+
|
112
|
+
* Standard Struct dosen't check member-name.
|
113
|
+
NoGuard = Struct.new :object_id, :'? !'
|
114
|
+
noguard = NoGuard.new false
|
115
|
+
noguard.object_id #=> false
|
116
|
+
noguard.methods.include?(:'? !') #=> false(lost!!)
|
117
|
+
|
118
|
+
* Striuct provides safety levels for this. (default: :prevent)
|
119
|
+
class SafetyNaming < Striuct.new
|
120
|
+
begin
|
121
|
+
member :object_id
|
122
|
+
rescue
|
123
|
+
p $!
|
124
|
+
end
|
125
|
+
|
126
|
+
begin
|
127
|
+
member :'? !'
|
128
|
+
rescue
|
129
|
+
p $!
|
130
|
+
end
|
131
|
+
|
132
|
+
# set lower
|
133
|
+
protect_level :struct
|
134
|
+
|
135
|
+
member :object_id, :'? !'
|
136
|
+
end
|
137
|
+
|
138
|
+
==== Support utils
|
139
|
+
|
140
|
+
* valid? / acccept? / sufficient? # can set a argument to a member
|
141
|
+
* conditionable? # can set a condition for any members
|
142
|
+
* inference? # inference member and no passed any object
|
143
|
+
* restrict? # has any conditions for a member
|
144
|
+
* strict? # now, all members are passed any conditions
|
145
|
+
* secure? # instance and class are fixed and strict
|
146
|
+
* cname? # can use member name under protect level
|
147
|
+
|
148
|
+
=== Struct+ "Handy"
|
149
|
+
|
150
|
+
==== Flavor
|
151
|
+
|
152
|
+
* Block with member macro, it is called "flavor" at here.
|
153
|
+
Below cases for type cast.
|
104
154
|
class User2 < Striuct.new
|
105
155
|
member :age, /\A\d+\z/, Numeric do |arg|
|
106
156
|
Integer arg
|
@@ -117,13 +167,11 @@ Handy and safty than Ruby's Standard Struct.
|
|
117
167
|
user2.age = '10' #=> 10(Fixnum)
|
118
168
|
|
119
169
|
user2.name = 10 #=> :10(Symbol)
|
170
|
+
user2.name = Class #=> :Class(Symbol)
|
120
171
|
|
121
|
-
|
122
|
-
user.strict? #=> true
|
123
|
-
user.address.clear
|
124
|
-
user.strict? #=> false
|
172
|
+
==== Default
|
125
173
|
|
126
|
-
*
|
174
|
+
* provides default value
|
127
175
|
class User3 < Striuct.new
|
128
176
|
member :lank, Fixnum
|
129
177
|
default :lank, 3
|
@@ -133,62 +181,71 @@ Handy and safty than Ruby's Standard Struct.
|
|
133
181
|
user3 = User3.new
|
134
182
|
user3.lank #=> 3
|
135
183
|
|
136
|
-
* Standard Struct always define "nil is default".
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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!!
|
184
|
+
* Standard Struct always define "nil is default". Realy?
|
185
|
+
user3.name #=> nil
|
186
|
+
user3.assign? :name #=> false
|
187
|
+
user3.name = nil
|
188
|
+
user3.assign? :name #=> true
|
147
189
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
p $!
|
154
|
-
end
|
155
|
-
|
156
|
-
begin
|
157
|
-
member :'? !'
|
158
|
-
rescue
|
159
|
-
p $!
|
160
|
-
end
|
161
|
-
|
162
|
-
protect_level :struct
|
163
|
-
|
164
|
-
member :__send__, :'? !'
|
190
|
+
==== Alias
|
191
|
+
|
192
|
+
* alias member name
|
193
|
+
class User3
|
194
|
+
alias_member :position, :lank
|
165
195
|
end
|
196
|
+
|
197
|
+
user3.lank.equal? user3.position #=> true
|
198
|
+
user3[:lank].equal? user3[:position] #=> true
|
199
|
+
user3[:position] = 4
|
200
|
+
user3.lank #=> 4
|
201
|
+
|
202
|
+
==== Inherit
|
203
|
+
|
204
|
+
* (writing...)
|
205
|
+
|
206
|
+
==== Lock
|
166
207
|
|
208
|
+
* (writing...)
|
167
209
|
|
168
|
-
|
169
|
-
Sth1 = Striuct.new :id, :last_name, :family_name, :address, :age
|
210
|
+
==== New Constructors
|
170
211
|
|
171
|
-
|
212
|
+
* Subclass.define reject floating object.
|
213
|
+
* block parameter is new instance
|
214
|
+
* except if no finished to assign each member
|
215
|
+
* returning object is tested strict(optional)
|
216
|
+
* returning object is locked(optional)
|
217
|
+
user3 = User3.define do |r|
|
218
|
+
r.lank = 10
|
219
|
+
r.name = 'foo'
|
220
|
+
end
|
221
|
+
|
222
|
+
* Subclass.[](load_pairs) make from Hash and like Hash
|
223
|
+
user3 = User3[lank: 10, name: 'foo']
|
224
|
+
|
225
|
+
=== Almost interfaces are keeping Struct has.
|
226
|
+
|
227
|
+
Sth1 = Striuct.new do
|
172
228
|
def my_special_method
|
173
229
|
end
|
174
230
|
end
|
175
231
|
|
176
|
-
|
232
|
+
Sth1.new.respond_to?(:my_special_method) #=> true
|
233
|
+
|
234
|
+
=== HashLike
|
235
|
+
|
236
|
+
* some interfaces import from Hash
|
177
237
|
|
178
|
-
*
|
179
|
-
|
238
|
+
* easy cast to Hash
|
239
|
+
user3.to_h #=> {:lank=>3, :name=>nil}
|
180
240
|
|
181
|
-
* run example.rb
|
182
241
|
|
183
|
-
|
184
|
-
https://github.com/kachick/striuct/wiki/EasyGuide
|
242
|
+
== Note
|
185
243
|
|
244
|
+
* Documents are poor
|
186
245
|
|
187
246
|
== REQUIREMENTS
|
188
247
|
|
189
|
-
|
190
|
-
* 1.9.3
|
191
|
-
* 1.9.2
|
248
|
+
* Ruby 1.9.2 and later (tested 1.9.2, 1.9.3)
|
192
249
|
|
193
250
|
== INSTALL
|
194
251
|
|
data/Rakefile
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
gem 'hoe', '
|
2
|
+
gem 'hoe', '~> 2.13.0'
|
3
3
|
require 'hoe'
|
4
4
|
require 'fileutils'
|
5
5
|
|
@@ -10,8 +10,10 @@ Hoe.plugin :newgem
|
|
10
10
|
# Generate all the Rake tasks
|
11
11
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
12
12
|
$hoe = Hoe.spec 'striuct' do
|
13
|
-
|
14
|
-
self.rubyforge_name = self.name
|
13
|
+
developer 'Kenichi Kamiya', 'kachick1+ruby@gmail.com'
|
14
|
+
self.rubyforge_name = self.name
|
15
|
+
require_ruby_version '>= 1.9.2'
|
16
|
+
dependency 'yard', '~> 0.7.4', :development
|
15
17
|
end
|
16
18
|
|
17
19
|
require 'newgem/tasks'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#/usr/bin/ruby -w
|
2
|
+
|
3
|
+
require 'benchmark'
|
4
|
+
require_relative '../lib/striuct'
|
5
|
+
|
6
|
+
XStruct = Struct.new :any, :no_use1, :no_use2
|
7
|
+
|
8
|
+
XStriuct = Striuct.define do
|
9
|
+
member :any
|
10
|
+
member :int, Integer
|
11
|
+
member :truthy, ->v{v}
|
12
|
+
end
|
13
|
+
|
14
|
+
xstruct = XStruct.new
|
15
|
+
xstriuct = XStriuct.new
|
16
|
+
|
17
|
+
TIMES = 100000
|
18
|
+
OBJ = 123
|
19
|
+
|
20
|
+
Benchmark.bm do |bm|
|
21
|
+
bm.report 'Struct(equal Noguard): Setter' do
|
22
|
+
TIMES.times do
|
23
|
+
xstruct.any = OBJ
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
bm.report 'Struct: Reader' do
|
28
|
+
TIMES.times do
|
29
|
+
xstruct.any
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
bm.report 'Striuct(when Noguard): Setter' do
|
34
|
+
TIMES.times do
|
35
|
+
xstriuct.any = OBJ
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
bm.report 'Striuct(guard under class): Setter' do
|
40
|
+
TIMES.times do
|
41
|
+
xstriuct.int = OBJ
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
bm.report 'Striuct(guard under function)' do
|
46
|
+
TIMES.times do
|
47
|
+
xstriuct.truthy = OBJ
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
bm.report 'Striuct: Reader' do
|
52
|
+
TIMES.times do
|
53
|
+
xstriuct.any
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,27 +1,27 @@
|
|
1
1
|
#/usr/bin/ruby -w
|
2
2
|
|
3
|
-
require_relative 'lib/striuct'
|
3
|
+
require_relative '../lib/striuct'
|
4
4
|
|
5
5
|
def debug(message)
|
6
|
-
puts "line: #{caller
|
6
|
+
puts "line: #{caller.first.slice(/:(\w+)/, 1)}"
|
7
7
|
puts message.inspect, '-' * 80
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
|
11
|
+
# 1. Struct+ "Secure"
|
12
|
+
|
13
|
+
# macro "member" provides to use condtions
|
11
14
|
class User < Striuct.new
|
12
|
-
member :id,
|
13
|
-
member :
|
14
|
-
member :
|
15
|
-
member :name, /\A\w+\z/, /\A\w+ \w+\z/
|
15
|
+
member :id, Integer
|
16
|
+
member :age, (20..140)
|
17
|
+
member :name, OR(/\A\w+\z/, /\A\w+ \w+\z/)
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
user = User.new 128381, 'Tokyo Japan', 20
|
20
|
+
user = User.new 128381, 20
|
20
21
|
debug user
|
21
22
|
|
22
|
-
# pass
|
23
23
|
user.age = 30
|
24
|
-
user
|
24
|
+
user[2] = 'taro yamada'
|
25
25
|
debug user
|
26
26
|
|
27
27
|
# fail (Exception Striuct::ConditionError)
|
@@ -31,12 +31,6 @@ rescue
|
|
31
31
|
debug $!
|
32
32
|
end
|
33
33
|
|
34
|
-
begin
|
35
|
-
user[1] = 'Tokyo-to'
|
36
|
-
rescue
|
37
|
-
debug $!
|
38
|
-
end
|
39
|
-
|
40
34
|
begin
|
41
35
|
user.age = 19
|
42
36
|
rescue
|
@@ -44,25 +38,19 @@ rescue
|
|
44
38
|
end
|
45
39
|
|
46
40
|
begin
|
47
|
-
user
|
41
|
+
user[2] = 'typo! name'
|
48
42
|
rescue
|
49
43
|
debug $!
|
50
44
|
end
|
51
45
|
|
52
|
-
|
53
|
-
debug user
|
54
|
-
debug user.strict?
|
55
|
-
debug user
|
56
|
-
debug user.strict?
|
57
|
-
|
58
|
-
# more detail checker do you need, you can use functional object.
|
46
|
+
# more detail checker do you need, use functional object
|
59
47
|
module Game
|
60
48
|
class Character
|
61
49
|
end
|
62
50
|
|
63
51
|
class DB < Striuct.new
|
64
|
-
member :monsters,
|
65
|
-
member :characters,
|
52
|
+
member :monsters, ->list{(list - characters).empty?}
|
53
|
+
member :characters, GENERICS(Character)
|
66
54
|
end
|
67
55
|
|
68
56
|
monster = Character.new
|
@@ -78,7 +66,7 @@ module Game
|
|
78
66
|
debug db
|
79
67
|
|
80
68
|
begin
|
81
|
-
db.monsters = [
|
69
|
+
db.monsters = [Character.new]
|
82
70
|
rescue
|
83
71
|
debug $!
|
84
72
|
end
|
@@ -87,10 +75,10 @@ module Game
|
|
87
75
|
debug db
|
88
76
|
end
|
89
77
|
|
90
|
-
# "inference", check under first passed object
|
78
|
+
# through "inference", and check under first passed object class
|
91
79
|
class FlexibleContainer < Striuct.new
|
92
80
|
member :anything, inference
|
93
|
-
member :number, inference
|
81
|
+
member :number, Numeric, inference
|
94
82
|
end
|
95
83
|
|
96
84
|
fc1, fc2 = FlexibleContainer.new, FlexibleContainer.new
|
@@ -127,15 +115,43 @@ rescue
|
|
127
115
|
debug $!
|
128
116
|
end
|
129
117
|
|
130
|
-
|
131
|
-
|
118
|
+
# Standard Struct not check member name.
|
119
|
+
NoGuard = Struct.new :__send__, :'? !'
|
120
|
+
noguard = NoGuard.new false
|
121
|
+
debug noguard.__send__
|
122
|
+
debug noguard.methods.include?(:'? !') # lost!!
|
123
|
+
|
124
|
+
# Striuct provides safety levels for naming.
|
125
|
+
class SafetyNaming < Striuct.new
|
126
|
+
begin
|
127
|
+
member :__send__
|
128
|
+
rescue
|
129
|
+
debug $!
|
130
|
+
end
|
131
|
+
|
132
|
+
begin
|
133
|
+
member :'? !'
|
134
|
+
rescue
|
135
|
+
debug $!
|
136
|
+
end
|
137
|
+
|
138
|
+
# set lower
|
139
|
+
protect_level :struct
|
140
|
+
|
141
|
+
member :__send__, :'? !'
|
142
|
+
end
|
143
|
+
|
144
|
+
# 2. Struct+ "Handy"
|
145
|
+
|
146
|
+
# to through block called "flavor"
|
147
|
+
# below case for type cast
|
132
148
|
class User2 < Striuct.new
|
133
149
|
member :age, /\A\d+\z/, Numeric do |arg|
|
134
150
|
Integer arg
|
135
151
|
end
|
136
152
|
|
137
|
-
member :name, ->v{v.respond_to? :
|
138
|
-
v.
|
153
|
+
member :name, ->v{v.respond_to? :to_s} do |v|
|
154
|
+
v.to_s.to_sym
|
139
155
|
end
|
140
156
|
end
|
141
157
|
|
@@ -149,16 +165,13 @@ debug user2
|
|
149
165
|
user2.age = '10'
|
150
166
|
debug user2
|
151
167
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
end
|
168
|
+
user2.name = 10
|
169
|
+
debug user2
|
170
|
+
user2.name = Class
|
171
|
+
debug user2
|
157
172
|
|
158
|
-
|
159
|
-
debug user2.class
|
173
|
+
# Default value
|
160
174
|
|
161
|
-
# use default value
|
162
175
|
class User3 < Striuct.new
|
163
176
|
member :lank, Fixnum
|
164
177
|
default :lank, 3
|
@@ -174,41 +187,39 @@ debug user3.assign?(:name)
|
|
174
187
|
user3.name = nil
|
175
188
|
debug user3.assign?(:name)
|
176
189
|
|
177
|
-
#
|
178
|
-
NoGuard = Struct.new :__send__, :'? !'
|
179
|
-
noguard = NoGuard.new false
|
180
|
-
debug noguard.__send__
|
181
|
-
debug noguard.methods.include?(:'? !') # lost!!
|
190
|
+
# Alias
|
182
191
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
member :__send__, :'? !'
|
192
|
+
class User3
|
193
|
+
alias_member :position, :lank
|
194
|
+
end
|
195
|
+
|
196
|
+
debug user3.lank.equal?(user3.position)
|
197
|
+
debug user3[:lank].equal?(user3[:position])
|
198
|
+
user3[:position] = 4
|
199
|
+
debug user3.lank
|
200
|
+
|
201
|
+
# New Constructors
|
202
|
+
|
203
|
+
# Subclass.define reject floating object
|
204
|
+
# * except if no finished assign each members
|
205
|
+
# * return object is frozen
|
206
|
+
user3 = User3.define do |r|
|
207
|
+
r.lank = 10
|
208
|
+
r.name = 'foo'
|
201
209
|
end
|
202
210
|
|
211
|
+
debug user3
|
212
|
+
|
213
|
+
# Subclass.load_pairs easy make from Hash and like Hash
|
214
|
+
user3 = User3[lank:10, name: 'foo']
|
203
215
|
|
204
|
-
|
205
|
-
Sth1 = Striuct.new :id, :last_name, :family_name, :address, :age
|
216
|
+
debug user3
|
206
217
|
|
207
|
-
|
218
|
+
# 3. Keeping Struct's good interface
|
208
219
|
|
209
|
-
|
220
|
+
Sth1 = Striuct.new do
|
210
221
|
def my_special_method
|
211
222
|
end
|
212
223
|
end
|
213
224
|
|
214
|
-
debug
|
225
|
+
debug Sth1.new.respond_to?(:my_special_method)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#/usr/bin/ruby -w
|
2
|
+
|
3
|
+
require_relative '../lib/striuct'
|
4
|
+
|
5
|
+
class User < Striuct.new
|
6
|
+
member :id, Integer
|
7
|
+
member :age, (20..140)
|
8
|
+
end
|
9
|
+
|
10
|
+
user = User.new
|
11
|
+
|
12
|
+
begin
|
13
|
+
user[:id] = 10.0
|
14
|
+
rescue
|
15
|
+
puts $!.backtrace
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
user.age = 19
|
20
|
+
rescue
|
21
|
+
puts $!.backtrace
|
22
|
+
end
|
23
|
+
|
24
|
+
puts '-' * 80
|
25
|
+
|
26
|
+
$stdout.flush
|
27
|
+
|
28
|
+
user.age = 19
|