blobject 0.3.3 → 0.3.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/.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
|