blobject 0.3.3 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.markdown +67 -13
- data/{blob_defn.png → assets/blob_defn.png} +0 -0
- data/{blobject.png → assets/blobject.png} +0 -0
- data/doc/Blobject.html +1393 -0
- data/doc/_index.html +110 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.README.html +269 -0
- data/doc/file_list.html +55 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +269 -0
- data/doc/js/app.js +208 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +172 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/blobject/version.rb +2 -2
- data/lib/blobject.rb +73 -61
- data/spec/blobject_spec.rb +50 -6
- metadata +28 -13
- data/README.md_ +0 -145
@@ -0,0 +1,172 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
6
|
+
|
7
|
+
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" charset="utf-8" />
|
8
|
+
|
9
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
14
|
+
|
15
|
+
<script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
|
16
|
+
|
17
|
+
|
18
|
+
<base id="base_target" target="_parent" />
|
19
|
+
</head>
|
20
|
+
<body>
|
21
|
+
<script type="text/javascript" charset="utf-8">
|
22
|
+
if (window.top.frames.main) {
|
23
|
+
document.getElementById('base_target').target = 'main';
|
24
|
+
document.body.className = 'frames';
|
25
|
+
}
|
26
|
+
</script>
|
27
|
+
<div id="content">
|
28
|
+
<h1 id="full_list_header">Method List</h1>
|
29
|
+
<div id="nav">
|
30
|
+
|
31
|
+
<span><a target="_self" href="class_list.html">
|
32
|
+
Classes
|
33
|
+
</a></span>
|
34
|
+
|
35
|
+
<span><a target="_self" href="method_list.html">
|
36
|
+
Methods
|
37
|
+
</a></span>
|
38
|
+
|
39
|
+
<span><a target="_self" href="file_list.html">
|
40
|
+
Files
|
41
|
+
</a></span>
|
42
|
+
|
43
|
+
</div>
|
44
|
+
<div id="search">Search: <input type="text" /></div>
|
45
|
+
|
46
|
+
<ul id="full_list" class="method">
|
47
|
+
|
48
|
+
|
49
|
+
<li class="r1 ">
|
50
|
+
<span class='object_link'><a href="Blobject.html#%3D%3D-instance_method" title="Blobject#== (method)">#==</a></span>
|
51
|
+
|
52
|
+
<small>Blobject</small>
|
53
|
+
|
54
|
+
</li>
|
55
|
+
|
56
|
+
|
57
|
+
<li class="r2 ">
|
58
|
+
<span class='object_link'><a href="Blobject.html#%5B%5D-instance_method" title="Blobject#[] (method)">#[]</a></span>
|
59
|
+
|
60
|
+
<small>Blobject</small>
|
61
|
+
|
62
|
+
</li>
|
63
|
+
|
64
|
+
|
65
|
+
<li class="r1 ">
|
66
|
+
<span class='object_link'><a href="Blobject.html#%5B%5D%3D-instance_method" title="Blobject#[]= (method)">#[]=</a></span>
|
67
|
+
|
68
|
+
<small>Blobject</small>
|
69
|
+
|
70
|
+
</li>
|
71
|
+
|
72
|
+
|
73
|
+
<li class="r2 ">
|
74
|
+
<span class='object_link'><a href="Blobject.html#as_json-instance_method" title="Blobject#as_json (method)">#as_json</a></span>
|
75
|
+
|
76
|
+
<small>Blobject</small>
|
77
|
+
|
78
|
+
</li>
|
79
|
+
|
80
|
+
|
81
|
+
<li class="r1 ">
|
82
|
+
<span class='object_link'><a href="Blobject.html#freeze-instance_method" title="Blobject#freeze (method)">#freeze</a></span>
|
83
|
+
|
84
|
+
<small>Blobject</small>
|
85
|
+
|
86
|
+
</li>
|
87
|
+
|
88
|
+
|
89
|
+
<li class="r2 ">
|
90
|
+
<span class='object_link'><a href="Blobject.html#from_json-class_method" title="Blobject.from_json (method)">from_json</a></span>
|
91
|
+
|
92
|
+
<small>Blobject</small>
|
93
|
+
|
94
|
+
</li>
|
95
|
+
|
96
|
+
|
97
|
+
<li class="r1 ">
|
98
|
+
<span class='object_link'><a href="Blobject.html#from_yaml-class_method" title="Blobject.from_yaml (method)">from_yaml</a></span>
|
99
|
+
|
100
|
+
<small>Blobject</small>
|
101
|
+
|
102
|
+
</li>
|
103
|
+
|
104
|
+
|
105
|
+
<li class="r2 ">
|
106
|
+
<span class='object_link'><a href="Blobject.html#hash-instance_method" title="Blobject#hash (method)">#hash</a></span>
|
107
|
+
|
108
|
+
<small>Blobject</small>
|
109
|
+
|
110
|
+
</li>
|
111
|
+
|
112
|
+
|
113
|
+
<li class="r1 ">
|
114
|
+
<span class='object_link'><a href="Blobject.html#initialize-instance_method" title="Blobject#initialize (method)">#initialize</a></span>
|
115
|
+
|
116
|
+
<small>Blobject</small>
|
117
|
+
|
118
|
+
</li>
|
119
|
+
|
120
|
+
|
121
|
+
<li class="r2 ">
|
122
|
+
<span class='object_link'><a href="Blobject.html#inspect-instance_method" title="Blobject#inspect (method)">#inspect</a></span>
|
123
|
+
|
124
|
+
<small>Blobject</small>
|
125
|
+
|
126
|
+
</li>
|
127
|
+
|
128
|
+
|
129
|
+
<li class="r1 ">
|
130
|
+
<span class='object_link'><a href="Blobject.html#method_missing-instance_method" title="Blobject#method_missing (method)">#method_missing</a></span>
|
131
|
+
|
132
|
+
<small>Blobject</small>
|
133
|
+
|
134
|
+
</li>
|
135
|
+
|
136
|
+
|
137
|
+
<li class="r2 ">
|
138
|
+
<span class='object_link'><a href="Blobject.html#respond_to%3F-instance_method" title="Blobject#respond_to? (method)">#respond_to?</a></span>
|
139
|
+
|
140
|
+
<small>Blobject</small>
|
141
|
+
|
142
|
+
</li>
|
143
|
+
|
144
|
+
|
145
|
+
<li class="r1 ">
|
146
|
+
<span class='object_link'><a href="Blobject.html#to_hash-instance_method" title="Blobject#to_hash (method)">#to_hash</a></span>
|
147
|
+
|
148
|
+
<small>Blobject</small>
|
149
|
+
|
150
|
+
</li>
|
151
|
+
|
152
|
+
|
153
|
+
<li class="r2 ">
|
154
|
+
<span class='object_link'><a href="Blobject.html#to_json-instance_method" title="Blobject#to_json (method)">#to_json</a></span>
|
155
|
+
|
156
|
+
<small>Blobject</small>
|
157
|
+
|
158
|
+
</li>
|
159
|
+
|
160
|
+
|
161
|
+
<li class="r1 ">
|
162
|
+
<span class='object_link'><a href="Blobject.html#to_yaml-instance_method" title="Blobject#to_yaml (method)">#to_yaml</a></span>
|
163
|
+
|
164
|
+
<small>Blobject</small>
|
165
|
+
|
166
|
+
</li>
|
167
|
+
|
168
|
+
|
169
|
+
</ul>
|
170
|
+
</div>
|
171
|
+
</body>
|
172
|
+
</html>
|
@@ -0,0 +1,112 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.8.1
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
hasFrames = window.top.frames.main ? true : false;
|
19
|
+
relpath = '';
|
20
|
+
framesUrl = "frames.html#!" + escape(window.location.href);
|
21
|
+
</script>
|
22
|
+
|
23
|
+
|
24
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
25
|
+
|
26
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
27
|
+
|
28
|
+
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="header">
|
32
|
+
<div id="menu">
|
33
|
+
|
34
|
+
<a href="_index.html">Index</a> »
|
35
|
+
|
36
|
+
|
37
|
+
<span class="title">Top Level Namespace</span>
|
38
|
+
|
39
|
+
|
40
|
+
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<div id="search">
|
44
|
+
|
45
|
+
<a class="full_list_link" id="class_list_link"
|
46
|
+
href="class_list.html">
|
47
|
+
Class List
|
48
|
+
</a>
|
49
|
+
|
50
|
+
<a class="full_list_link" id="method_list_link"
|
51
|
+
href="method_list.html">
|
52
|
+
Method List
|
53
|
+
</a>
|
54
|
+
|
55
|
+
<a class="full_list_link" id="file_list_link"
|
56
|
+
href="file_list.html">
|
57
|
+
File List
|
58
|
+
</a>
|
59
|
+
|
60
|
+
</div>
|
61
|
+
<div class="clear"></div>
|
62
|
+
</div>
|
63
|
+
|
64
|
+
<iframe id="search_frame"></iframe>
|
65
|
+
|
66
|
+
<div id="content"><h1>Top Level Namespace
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
</h1>
|
71
|
+
|
72
|
+
<dl class="box">
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
</dl>
|
82
|
+
<div class="clear"></div>
|
83
|
+
|
84
|
+
<h2>Defined Under Namespace</h2>
|
85
|
+
<p class="children">
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
<strong class="classes">Classes:</strong> <span class='object_link'><a href="Blobject.html" title="Blobject (class)">Blobject</a></span>
|
91
|
+
|
92
|
+
|
93
|
+
</p>
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
</div>
|
104
|
+
|
105
|
+
<div id="footer">
|
106
|
+
Generated on Thu Jun 7 00:25:31 2012 by
|
107
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
108
|
+
0.8.1 (ruby-1.9.3).
|
109
|
+
</div>
|
110
|
+
|
111
|
+
</body>
|
112
|
+
</html>
|
data/lib/blobject/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
class Blobject
|
2
|
-
VERSION = '0.3.
|
3
|
-
end
|
2
|
+
VERSION = '0.3.7'
|
3
|
+
end
|
data/lib/blobject.rb
CHANGED
@@ -2,49 +2,52 @@ require 'json'
|
|
2
2
|
require 'yaml'
|
3
3
|
require_relative 'blobject/version'
|
4
4
|
|
5
|
+
# Wraps a hash to provide arbitrarily nested object-style attribute access
|
5
6
|
class Blobject
|
6
7
|
|
7
8
|
# filter :to_ary else Blobject#to_ary returns a
|
8
9
|
# blobject which is not cool, especially if you are puts.
|
9
10
|
ProhibitedNames = [:to_ary]
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
# pass an optional hash of values to preload
|
13
|
+
# you can also pass a block, the new Blobject will be yield
|
13
14
|
def initialize hash = {}
|
14
15
|
|
15
|
-
@hash =
|
16
|
+
@hash = Hash.new
|
16
17
|
|
17
|
-
|
18
|
-
unless key.
|
19
|
-
|
20
|
-
key = key.to_sym
|
21
|
-
@hash[key] = value
|
22
|
-
end
|
18
|
+
hash.each do |key, value|
|
19
|
+
key = key.to_sym unless key.is_a? Symbol
|
20
|
+
@hash[key] = value
|
23
21
|
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
@hash[name] = Blobject.new node
|
28
|
-
end
|
23
|
+
@hash.each do |name, node|
|
24
|
+
@hash[name] = self.class.send(:__blobjectify__, node)
|
29
25
|
end
|
30
26
|
|
31
27
|
yield self if block_given?
|
32
28
|
end
|
33
29
|
|
30
|
+
def empty?
|
31
|
+
@hash.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
# delegates to the internal Hash
|
34
35
|
def inspect
|
35
36
|
|
36
37
|
@hash.inspect
|
37
38
|
end
|
38
39
|
|
40
|
+
# access the internal hash. be careful, this is _not_ a copy
|
39
41
|
def hash
|
40
42
|
|
41
43
|
@hash
|
42
44
|
end
|
43
45
|
|
46
|
+
# creates a recursive copy of the internal hash
|
44
47
|
def to_hash
|
45
48
|
|
46
49
|
h = hash.dup
|
47
|
-
|
50
|
+
@hash.each do |name, node|
|
48
51
|
h[name] = node.to_hash if node.respond_to? :to_hash
|
49
52
|
end
|
50
53
|
h
|
@@ -60,12 +63,13 @@ class Blobject
|
|
60
63
|
# assignment in conditionals is usually a bad smell, here it helps minimize regex matching
|
61
64
|
when (name = method[/^\w+$/, 0]) && params.length == 0
|
62
65
|
# the call is an attribute reader
|
63
|
-
|
64
|
-
|
66
|
+
|
67
|
+
return self.class.new.freeze if frozen? and not @hash.has_key?(method)
|
65
68
|
self.class.send :__define_attribute__, name
|
66
69
|
|
67
70
|
return send(method) if @hash.has_key? method
|
68
71
|
|
72
|
+
# close the scope for storing call chain
|
69
73
|
parent = self
|
70
74
|
nested_blobject = self.class.new
|
71
75
|
|
@@ -106,85 +110,77 @@ class Blobject
|
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
113
|
+
# compares Blobjects to Blobjects or Hashes
|
109
114
|
def == other
|
110
115
|
return @hash == other.hash if other.class <= Blobject
|
111
116
|
return @hash == other if other.class <= Hash
|
112
117
|
super
|
113
118
|
end
|
114
119
|
|
120
|
+
# hash-like access to the Blobject's attributes
|
115
121
|
def [] name
|
116
122
|
|
117
123
|
send name
|
118
124
|
end
|
119
125
|
|
126
|
+
# hash-like attribtue setter
|
120
127
|
def []= name, value
|
121
128
|
|
122
129
|
send "#{name.to_s}=", value
|
123
130
|
end
|
124
131
|
|
132
|
+
# freeze a Blobject to prevent it being modified
|
125
133
|
def freeze
|
126
|
-
__visit_subtree__ { |name, node| node.freeze }
|
127
134
|
@hash.freeze
|
128
135
|
super
|
129
136
|
end
|
130
137
|
|
138
|
+
def freeze_r
|
139
|
+
self.class.send(:__freeze_r__, self)
|
140
|
+
freeze
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# returns a hash which can be serialized as json.
|
145
|
+
# this is for use in rails controllers: `render json: blobject`
|
131
146
|
def as_json *args
|
132
147
|
return hash.as_json(*args) if hash.respond_to? :as_json
|
133
148
|
to_hash
|
134
149
|
end
|
135
150
|
|
151
|
+
# serialize the Blobject as a json string
|
136
152
|
def to_json *args
|
137
153
|
as_json.to_json *args
|
138
154
|
end
|
139
155
|
|
140
|
-
|
141
|
-
|
142
|
-
to_hash
|
143
|
-
end
|
144
|
-
|
156
|
+
# serialize the Blobject as a yaml string
|
145
157
|
def to_yaml
|
146
158
|
|
147
159
|
as_yaml.to_yaml
|
148
160
|
end
|
149
161
|
|
162
|
+
# get a Blobject from a json string
|
163
|
+
# if the yaml string describes an array, an array will be returned
|
150
164
|
def self.from_json json
|
151
165
|
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.from_json! json
|
156
|
-
|
157
|
-
__from_hash_or_array__(JSON.parse(json))
|
166
|
+
__blobjectify__(JSON.parse(json))
|
158
167
|
end
|
159
168
|
|
169
|
+
# get a Blobject from a yaml string
|
170
|
+
# if the yaml string describes an array, an array will be returned
|
160
171
|
def self.from_yaml yaml
|
161
172
|
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
def self.from_yaml! yaml
|
166
|
-
|
167
|
-
__from_hash_or_array__(YAML.load(yaml))
|
173
|
+
__blobjectify__(YAML.load(yaml))
|
168
174
|
end
|
169
175
|
|
170
176
|
private
|
171
177
|
# to avoid naming collisions private method names are prefixed and suffix with double unerscores (__)
|
172
178
|
|
173
|
-
|
174
|
-
|
175
|
-
@hash.each do |name, node|
|
176
|
-
|
177
|
-
if node.class <= Array
|
178
|
-
node.flatten.each do |node_node|
|
179
|
-
block.call(nil, node_node, &block)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
block.call name, node, &block
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
179
|
+
# Used to tag and reraise errors from a Blobject
|
180
|
+
# Refer to "Tagging exceptions with modules" on p97 in Exceptional Ruby by Avdi Grimm
|
187
181
|
# errors from this library can be handled with rescue Blobject::Error
|
182
|
+
module Error; end
|
183
|
+
|
188
184
|
def __tag_and_raise__ e
|
189
185
|
raise e
|
190
186
|
rescue
|
@@ -196,19 +192,35 @@ private
|
|
196
192
|
|
197
193
|
private
|
198
194
|
|
199
|
-
def
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
e
|
207
|
-
end
|
195
|
+
def __freeze_r__ object
|
196
|
+
|
197
|
+
case object
|
198
|
+
when Array
|
199
|
+
return object.each do |e|
|
200
|
+
e.freeze
|
201
|
+
__freeze_r__(e)
|
208
202
|
end
|
203
|
+
when Hash
|
204
|
+
return object.each do |k, v|
|
205
|
+
v.freeze
|
206
|
+
__freeze_r__(v)
|
207
|
+
end
|
208
|
+
when Blobject
|
209
|
+
object.freeze
|
210
|
+
__freeze_r__ object.hash
|
211
|
+
else
|
212
|
+
object.freeze
|
209
213
|
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def __blobjectify__ object
|
210
217
|
|
211
|
-
|
218
|
+
array = object if object.is_a? Array
|
219
|
+
hash = object if object.is_a? Hash
|
220
|
+
|
221
|
+
return array.map{|a| __blobjectify__(a)} if array
|
222
|
+
return Blobject.new(hash) if hash
|
223
|
+
return object
|
212
224
|
end
|
213
225
|
|
214
226
|
def __define_attribute__ name
|
@@ -222,7 +234,7 @@ private
|
|
222
234
|
unless methods.include? setter_name
|
223
235
|
self.send :define_method, setter_name do |value|
|
224
236
|
begin
|
225
|
-
value = self.class.
|
237
|
+
value = self.class.send(:__blobjectify__, value) if value.is_a?(Hash) or value.is_a?(Array)
|
226
238
|
@hash[name] = value
|
227
239
|
rescue ex
|
228
240
|
__tag_and_raise__(ex)
|
@@ -236,9 +248,9 @@ private
|
|
236
248
|
|
237
249
|
value = @hash[name]
|
238
250
|
|
239
|
-
if value.nil?
|
251
|
+
if value.nil?
|
240
252
|
value = self.class.new
|
241
|
-
@hash[name] = value
|
253
|
+
@hash[name] = value unless frozen?
|
242
254
|
end
|
243
255
|
|
244
256
|
value
|
data/spec/blobject_spec.rb
CHANGED
@@ -47,6 +47,43 @@ describe Blobject do
|
|
47
47
|
assert_equal b.name.surname, "Jones"
|
48
48
|
end
|
49
49
|
|
50
|
+
it 'recursively blobjectifies assigned values' do
|
51
|
+
b.data = {name: 'jim', number: 144}
|
52
|
+
b.data.must_be_instance_of Blobject
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'recursively blobjectifies assigned arrays' do
|
56
|
+
b.data = [{name: 'jim', number: 144}, [{name: 'jam', number: 147}]]
|
57
|
+
b.data[0].must_be_instance_of Blobject
|
58
|
+
b.data[1][0].must_be_instance_of Blobject
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can indicate whether it is empty' do
|
62
|
+
b = Blobject.new
|
63
|
+
b.must_be :empty?
|
64
|
+
b.name = "something"
|
65
|
+
b.wont_be :empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'hash-like access' do
|
69
|
+
|
70
|
+
it 'allows hash-style setters' do
|
71
|
+
|
72
|
+
b[:foo] = 123
|
73
|
+
b['bar'] = 456
|
74
|
+
|
75
|
+
assert_equal "#{b.foo}#{b.bar}", '123456'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'allows hash-style getters' do
|
79
|
+
|
80
|
+
b.name = "Jimmy"
|
81
|
+
|
82
|
+
assert_equal b[:name] , "Jimmy"
|
83
|
+
assert_equal b['name'], "Jimmy"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
50
87
|
describe 'respond_to?' do
|
51
88
|
|
52
89
|
it 'returns true if the blobject has the corresponding member' do
|
@@ -233,7 +270,14 @@ describe Blobject do
|
|
233
270
|
end
|
234
271
|
end
|
235
272
|
|
236
|
-
describe '
|
273
|
+
describe 'freeze' do
|
274
|
+
it 'freezes the internal hash' do
|
275
|
+
b.freeze
|
276
|
+
b.hash.must_be :frozen?
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
describe 'freeze_r' do
|
237
281
|
|
238
282
|
before :each do
|
239
283
|
list_element = Blobject.new
|
@@ -242,7 +286,7 @@ describe Blobject do
|
|
242
286
|
b.data.list = [1, 2, 3, list_element]
|
243
287
|
b.data.inner_hash = {:inner => {:one => 1}}
|
244
288
|
|
245
|
-
b.
|
289
|
+
b.freeze_r
|
246
290
|
end
|
247
291
|
|
248
292
|
it 'still provides access' do
|
@@ -268,10 +312,10 @@ describe Blobject do
|
|
268
312
|
proc { b.hello = 123 }.must_raise RuntimeError
|
269
313
|
end
|
270
314
|
|
271
|
-
it 'returns
|
272
|
-
|
315
|
+
it 'still returns a blobject when trying to get an attribute' do
|
316
|
+
b.meow_face.must_be_instance_of Blobject
|
273
317
|
# check again to test memoized method
|
274
|
-
|
275
|
-
|
318
|
+
b.meow_face.must_be_instance_of Blobject
|
319
|
+
end
|
276
320
|
end
|
277
321
|
end
|