rep 0.1.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,375 @@
1
+ /*! normalize.css v2.0.1 | MIT License | git.io/normalize */
2
+
3
+ /* ==========================================================================
4
+ HTML5 display definitions
5
+ ========================================================================== */
6
+
7
+ /*
8
+ * Corrects `block` display not defined in IE 8/9.
9
+ */
10
+
11
+ article,
12
+ aside,
13
+ details,
14
+ figcaption,
15
+ figure,
16
+ footer,
17
+ header,
18
+ hgroup,
19
+ nav,
20
+ section,
21
+ summary {
22
+ display: block;
23
+ }
24
+
25
+ /*
26
+ * Corrects `inline-block` display not defined in IE 8/9.
27
+ */
28
+
29
+ audio,
30
+ canvas,
31
+ video {
32
+ display: inline-block;
33
+ }
34
+
35
+ /*
36
+ * Prevents modern browsers from displaying `audio` without controls.
37
+ * Remove excess height in iOS 5 devices.
38
+ */
39
+
40
+ audio:not([controls]) {
41
+ display: none;
42
+ height: 0;
43
+ }
44
+
45
+ /*
46
+ * Addresses styling for `hidden` attribute not present in IE 8/9.
47
+ */
48
+
49
+ [hidden] {
50
+ display: none;
51
+ }
52
+
53
+ /* ==========================================================================
54
+ Base
55
+ ========================================================================== */
56
+
57
+ /*
58
+ * 1. Sets default font family to sans-serif.
59
+ * 2. Prevents iOS text size adjust after orientation change, without disabling
60
+ * user zoom.
61
+ */
62
+
63
+ html {
64
+ font-family: sans-serif; /* 1 */
65
+ -webkit-text-size-adjust: 100%; /* 2 */
66
+ -ms-text-size-adjust: 100%; /* 2 */
67
+ }
68
+
69
+ /*
70
+ * Removes default margin.
71
+ */
72
+
73
+ body {
74
+ margin: 0;
75
+ }
76
+
77
+ /* ==========================================================================
78
+ Links
79
+ ========================================================================== */
80
+
81
+ /*
82
+ * Addresses `outline` inconsistency between Chrome and other browsers.
83
+ */
84
+
85
+ a:focus {
86
+ outline: thin dotted;
87
+ }
88
+
89
+ /*
90
+ * Improves readability when focused and also mouse hovered in all browsers.
91
+ */
92
+
93
+ a:active,
94
+ a:hover {
95
+ outline: 0;
96
+ }
97
+
98
+ /* ==========================================================================
99
+ Typography
100
+ ========================================================================== */
101
+
102
+ /*
103
+ * Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
104
+ * Safari 5, and Chrome.
105
+ */
106
+
107
+ h1 {
108
+ font-size: 2em;
109
+ }
110
+
111
+ /*
112
+ * Addresses styling not present in IE 8/9, Safari 5, and Chrome.
113
+ */
114
+
115
+ abbr[title] {
116
+ border-bottom: 1px dotted;
117
+ }
118
+
119
+ /*
120
+ * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
121
+ */
122
+
123
+ b,
124
+ strong {
125
+ font-weight: bold;
126
+ }
127
+
128
+ /*
129
+ * Addresses styling not present in Safari 5 and Chrome.
130
+ */
131
+
132
+ dfn {
133
+ font-style: italic;
134
+ }
135
+
136
+ /*
137
+ * Addresses styling not present in IE 8/9.
138
+ */
139
+
140
+ mark {
141
+ background: #ff0;
142
+ color: #000;
143
+ }
144
+
145
+
146
+ /*
147
+ * Corrects font family set oddly in Safari 5 and Chrome.
148
+ */
149
+
150
+ code,
151
+ kbd,
152
+ pre,
153
+ samp {
154
+ font-family: monospace, serif;
155
+ font-size: 1em;
156
+ }
157
+
158
+ /*
159
+ * Improves readability of pre-formatted text in all browsers.
160
+ */
161
+
162
+ pre {
163
+ white-space: pre;
164
+ white-space: pre-wrap;
165
+ word-wrap: break-word;
166
+ }
167
+
168
+ /*
169
+ * Sets consistent quote types.
170
+ */
171
+
172
+ q {
173
+ quotes: "\201C" "\201D" "\2018" "\2019";
174
+ }
175
+
176
+ /*
177
+ * Addresses inconsistent and variable font size in all browsers.
178
+ */
179
+
180
+ small {
181
+ font-size: 80%;
182
+ }
183
+
184
+ /*
185
+ * Prevents `sub` and `sup` affecting `line-height` in all browsers.
186
+ */
187
+
188
+ sub,
189
+ sup {
190
+ font-size: 75%;
191
+ line-height: 0;
192
+ position: relative;
193
+ vertical-align: baseline;
194
+ }
195
+
196
+ sup {
197
+ top: -0.5em;
198
+ }
199
+
200
+ sub {
201
+ bottom: -0.25em;
202
+ }
203
+
204
+ /* ==========================================================================
205
+ Embedded content
206
+ ========================================================================== */
207
+
208
+ /*
209
+ * Removes border when inside `a` element in IE 8/9.
210
+ */
211
+
212
+ img {
213
+ border: 0;
214
+ }
215
+
216
+ /*
217
+ * Corrects overflow displayed oddly in IE 9.
218
+ */
219
+
220
+ svg:not(:root) {
221
+ overflow: hidden;
222
+ }
223
+
224
+ /* ==========================================================================
225
+ Figures
226
+ ========================================================================== */
227
+
228
+ /*
229
+ * Addresses margin not present in IE 8/9 and Safari 5.
230
+ */
231
+
232
+ figure {
233
+ margin: 0;
234
+ }
235
+
236
+ /* ==========================================================================
237
+ Forms
238
+ ========================================================================== */
239
+
240
+ /*
241
+ * Define consistent border, margin, and padding.
242
+ */
243
+
244
+ fieldset {
245
+ border: 1px solid #c0c0c0;
246
+ margin: 0 2px;
247
+ padding: 0.35em 0.625em 0.75em;
248
+ }
249
+
250
+ /*
251
+ * 1. Corrects color not being inherited in IE 8/9.
252
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
253
+ */
254
+
255
+ legend {
256
+ border: 0; /* 1 */
257
+ padding: 0; /* 2 */
258
+ }
259
+
260
+ /*
261
+ * 1. Corrects font family not being inherited in all browsers.
262
+ * 2. Corrects font size not being inherited in all browsers.
263
+ * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
264
+ */
265
+
266
+ button,
267
+ input,
268
+ select,
269
+ textarea {
270
+ font-family: inherit; /* 1 */
271
+ font-size: 100%; /* 2 */
272
+ margin: 0; /* 3 */
273
+ }
274
+
275
+ /*
276
+ * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
277
+ * the UA stylesheet.
278
+ */
279
+
280
+ button,
281
+ input {
282
+ line-height: normal;
283
+ }
284
+
285
+ /*
286
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
287
+ * and `video` controls.
288
+ * 2. Corrects inability to style clickable `input` types in iOS.
289
+ * 3. Improves usability and consistency of cursor style between image-type
290
+ * `input` and others.
291
+ */
292
+
293
+ button,
294
+ html input[type="button"], /* 1 */
295
+ input[type="reset"],
296
+ input[type="submit"] {
297
+ -webkit-appearance: button; /* 2 */
298
+ cursor: pointer; /* 3 */
299
+ }
300
+
301
+ /*
302
+ * Re-set default cursor for disabled elements.
303
+ */
304
+
305
+ button[disabled],
306
+ input[disabled] {
307
+ cursor: default;
308
+ }
309
+
310
+ /*
311
+ * 1. Addresses box sizing set to `content-box` in IE 8/9.
312
+ * 2. Removes excess padding in IE 8/9.
313
+ */
314
+
315
+ input[type="checkbox"],
316
+ input[type="radio"] {
317
+ box-sizing: border-box; /* 1 */
318
+ padding: 0; /* 2 */
319
+ }
320
+
321
+ /*
322
+ * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
323
+ * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
324
+ * (include `-moz` to future-proof).
325
+ */
326
+
327
+ input[type="search"] {
328
+ -webkit-appearance: textfield; /* 1 */
329
+ -moz-box-sizing: content-box;
330
+ -webkit-box-sizing: content-box; /* 2 */
331
+ box-sizing: content-box;
332
+ }
333
+
334
+ /*
335
+ * Removes inner padding and search cancel button in Safari 5 and Chrome
336
+ * on OS X.
337
+ */
338
+
339
+ input[type="search"]::-webkit-search-cancel-button,
340
+ input[type="search"]::-webkit-search-decoration {
341
+ -webkit-appearance: none;
342
+ }
343
+
344
+ /*
345
+ * Removes inner padding and border in Firefox 4+.
346
+ */
347
+
348
+ button::-moz-focus-inner,
349
+ input::-moz-focus-inner {
350
+ border: 0;
351
+ padding: 0;
352
+ }
353
+
354
+ /*
355
+ * 1. Removes default vertical scrollbar in IE 8/9.
356
+ * 2. Improves readability and alignment in all browsers.
357
+ */
358
+
359
+ textarea {
360
+ overflow: auto; /* 1 */
361
+ vertical-align: top; /* 2 */
362
+ }
363
+
364
+ /* ==========================================================================
365
+ Tables
366
+ ========================================================================== */
367
+
368
+ /*
369
+ * Remove most spacing between table cells.
370
+ */
371
+
372
+ table {
373
+ border-collapse: collapse;
374
+ border-spacing: 0;
375
+ }
data/docs/rep.html CHANGED
@@ -1,58 +1,41 @@
1
1
  <!DOCTYPE html>
2
+
2
3
  <html>
3
4
  <head>
4
- <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
5
  <title>rep.rb</title>
6
- <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
6
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
7
+ <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
8
+ <link rel="stylesheet" media="all" href="docco.css" />
7
9
  </head>
8
10
  <body>
9
- <div id='container'>
10
- <div id="background"></div>
11
- <div id="jump_to">
12
- Jump To &hellip;
13
- <div id="jump_wrapper">
14
- <div id="jump_page">
15
- <a class="source" href="rep.html">rep.rb</a>
16
- <a class="source" href="rep/version.html">version.rb</a>
17
- </div>
18
- </div>
19
- </div>
20
- <table cellspacing=0 cellpadding=0>
21
- <thead>
22
- <tr>
23
- <th class=docs><h1>rep.rb</h1></th>
24
- <th class=code></th>
25
- </tr>
26
- </thead>
27
- <tbody>
28
- <tr id='section-1'>
29
- <td class=docs>
30
- <div class="pilwrap">
31
- <a class="pilcrow" href="#section-1">&#182;</a>
32
- </div>
33
- <p><strong>Rep</strong> is a small module to endow any class to make json quickly. It solves four problems:</p>
34
-
11
+ <div id="container">
12
+ <div id="background"></div>
13
+
14
+ <ul class="sections">
15
+
16
+ <li id="title">
17
+ <div class="annotation">
18
+ <h1>rep.rb</h1>
19
+ </div>
20
+ </li>
21
+
22
+
23
+
24
+ <li id="section-1">
25
+ <div class="annotation">
26
+
27
+ <div class="pilwrap ">
28
+ <a class="pilcrow" href="#section-1">&#182;</a>
29
+ </div>
30
+ <p><strong>Rep</strong> is a small module to endow any class to make json quickly. It solves four problems:</p>
35
31
  <ol>
36
32
  <li>Enumerating top level keys for a json structure</li>
37
33
  <li>Providing a convention for the value of those keys</li>
38
- <li>Defining <code>attr_accessor</code>&rsquo;s that are prefilled from an options hash given to <code>#initialize</code></li>
34
+ <li>Defining <code>attr_accessor</code>&#39;s that are prefilled from an options hash given to <code>#initialize</code></li>
39
35
  <li>Sharing instances to help GC</li>
40
36
  </ol>
41
-
42
-
43
37
  <p>The code is available on <a href="http://github.com/myobie/rep">github</a>.</p>
44
- </td>
45
- <td class=code>
46
- <div class='highlight'><pre></pre></div>
47
- </td>
48
- </tr>
49
- <tr id='section-2'>
50
- <td class=docs>
51
- <div class="pilwrap">
52
- <a class="pilcrow" href="#section-2">&#182;</a>
53
- </div>
54
- <p><code>Forwardable</code> is in the stdlib and allows ruby objects to delegate methods off to other objects. An example:</p>
55
-
38
+ <p><code>Forwardable</code> is in the stdlib and allows ruby objects to delegate methods off to other objects. An example:</p>
56
39
  <pre><code>class A
57
40
  extend Forwardable
58
41
  delegate [:length, :first] =&gt; :@array
@@ -64,386 +47,423 @@ end
64
47
  A.new([1,2,3]).length # =&gt; 3
65
48
  A.new([1,2,3]).first # =&gt; 1
66
49
  </code></pre>
67
- </td>
68
- <td class=code>
69
- <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;forwardable&#39;</span></pre></div>
70
- </td>
71
- </tr>
72
- <tr id='section-3'>
73
- <td class=docs>
74
- <div class="pilwrap">
75
- <a class="pilcrow" href="#section-3">&#182;</a>
76
- </div>
77
- <p><code>JSON::generate</code> and <code>JSON::decode</code> are much safer to use than <code>Object#to_json</code>.</p>
78
- </td>
79
- <td class=code>
80
- <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;json&#39;</span>
81
-
82
- <span class="nb">require</span> <span class="s1">&#39;rep/version&#39;</span>
83
- <span class="k">module</span> <span class="nn">Rep</span></pre></div>
84
- </td>
85
- </tr>
86
- <tr id='section-4'>
87
- <td class=docs>
88
- <div class="pilwrap">
89
- <a class="pilcrow" href="#section-4">&#182;</a>
90
- </div>
91
- <p>All classes that <code>include Rep</code> are extended with <code>Forwardable</code>,
50
+ </div>
51
+
52
+ <div class="content"><div class='highlight'><pre><span class="hljs-keyword">require</span> <span class="hljs-string">'forwardable'</span></pre></div></div>
53
+
54
+ </li>
55
+
56
+
57
+ <li id="section-2">
58
+ <div class="annotation">
59
+
60
+ <div class="pilwrap ">
61
+ <a class="pilcrow" href="#section-2">&#182;</a>
62
+ </div>
63
+ <p><code>JSON::generate</code> and <code>JSON::decode</code> are much safer to use than <code>Object#to_json</code>.</p>
64
+
65
+ </div>
66
+
67
+ <div class="content"><div class='highlight'><pre><span class="hljs-keyword">require</span> <span class="hljs-string">'json'</span>
68
+
69
+ <span class="hljs-keyword">require</span> <span class="hljs-string">'rep/version'</span>
70
+ <span class="hljs-class"><span class="hljs-keyword">module</span> <span class="hljs-title">Rep</span></span></pre></div></div>
71
+
72
+ </li>
73
+
74
+
75
+ <li id="section-3">
76
+ <div class="annotation">
77
+
78
+ <div class="pilwrap ">
79
+ <a class="pilcrow" href="#section-3">&#182;</a>
80
+ </div>
81
+ <p>All classes that <code>include Rep</code> are extended with <code>Forwardable</code>,
92
82
  given some aliases, endowned with <code>HashieSupport</code> if Hashie is loaded,
93
- and given a delegate method if it doesn&rsquo;t already have one.</p>
94
- </td>
95
- <td class=code>
96
- <div class='highlight'><pre> <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">included</span><span class="p">(</span><span class="n">klass</span><span class="p">)</span>
97
- <span class="n">klass</span><span class="o">.</span><span class="n">extend</span> <span class="no">Forwardable</span>
98
- <span class="n">klass</span><span class="o">.</span><span class="n">extend</span> <span class="no">ClassMethods</span>
99
- <span class="n">klass</span><span class="o">.</span><span class="n">instance_eval</span> <span class="p">{</span>
100
- <span class="k">class</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span>
101
- <span class="k">unless</span> <span class="n">defined?</span><span class="p">(</span><span class="n">forward</span><span class="p">)</span>
102
- <span class="k">alias</span> <span class="n">forward</span> <span class="n">delegate</span>
103
- <span class="k">end</span>
104
-
105
- <span class="k">unless</span> <span class="n">defined?</span><span class="p">(</span><span class="n">fields</span><span class="p">)</span>
106
- <span class="k">alias</span> <span class="n">fields</span> <span class="n">json_fields</span>
107
- <span class="k">end</span>
108
- <span class="k">end</span>
109
-
110
- <span class="k">if</span> <span class="n">defined?</span><span class="p">(</span><span class="no">Mashed</span><span class="p">)</span>
111
- <span class="kp">include</span> <span class="no">MashedSupport</span>
112
- <span class="k">end</span>
113
- <span class="p">}</span>
114
- <span class="k">end</span></pre></div>
115
- </td>
116
- </tr>
117
- <tr id='section-5'>
118
- <td class=docs>
119
- <div class="pilwrap">
120
- <a class="pilcrow" href="#section-5">&#182;</a>
121
- </div>
122
- <p>Since a goal is to be able to share instances, we need an easy way to reset a
83
+ and given a delegate method if it doesn&#39;t already have one.</p>
84
+
85
+ </div>
86
+
87
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span><span class="hljs-keyword">self</span>.included(klass)
88
+ klass.extend <span class="hljs-constant">Forwardable</span>
89
+ klass.extend <span class="hljs-constant">ClassMethods</span>
90
+ klass.instance_eval {
91
+ <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-inheritance">&lt;</span><span class="hljs-inheritance">&lt; <span class="hljs-parent">self</span></span></span>
92
+ <span class="hljs-keyword">unless</span> <span class="hljs-keyword">defined</span>?(forward)
93
+ <span class="hljs-keyword">alias</span> forward delegate
94
+ <span class="hljs-keyword">end</span>
95
+
96
+ <span class="hljs-keyword">unless</span> <span class="hljs-keyword">defined</span>?(fields)
97
+ <span class="hljs-keyword">alias</span> fields json_fields
98
+ <span class="hljs-keyword">end</span>
99
+ <span class="hljs-keyword">end</span>
100
+
101
+ <span class="hljs-keyword">if</span> <span class="hljs-keyword">defined</span>?(<span class="hljs-constant">Mashed</span>)
102
+ <span class="hljs-keyword">include</span> <span class="hljs-constant">MashedSupport</span>
103
+ <span class="hljs-keyword">end</span>
104
+ }
105
+ <span class="hljs-keyword">end</span></pre></div></div>
106
+
107
+ </li>
108
+
109
+
110
+ <li id="section-4">
111
+ <div class="annotation">
112
+
113
+ <div class="pilwrap ">
114
+ <a class="pilcrow" href="#section-4">&#182;</a>
115
+ </div>
116
+ <p>Since a goal is to be able to share instances, we need an easy way to reset a
123
117
  shared instance back to factory defaults. If you memoize any methods that are
124
118
  not declared as json fields, then overried this method and set any memoized
125
119
  variables to nil, then super.</p>
126
- </td>
127
- <td class=code>
128
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">reset_for_json!</span>
129
- <span class="nb">self</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">all_json_methods</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">method_name</span><span class="o">|</span>
130
- <span class="nb">instance_variable_set</span><span class="p">(</span><span class="ss">:&quot;@</span><span class="si">#{</span><span class="n">method_name</span><span class="si">}</span><span class="ss">&quot;</span><span class="p">,</span> <span class="kp">nil</span><span class="p">)</span>
131
- <span class="k">end</span>
132
- <span class="k">end</span></pre></div>
133
- </td>
134
- </tr>
135
- <tr id='section-6'>
136
- <td class=docs>
137
- <div class="pilwrap">
138
- <a class="pilcrow" href="#section-6">&#182;</a>
139
- </div>
140
- <p>All the work of generating a hash from an instance is packaged up in one method. Since
120
+
121
+ </div>
122
+
123
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>reset_for_json!
124
+ <span class="hljs-keyword">self</span>.<span class="hljs-keyword">class</span>.all_json_methods.each <span class="hljs-keyword">do</span> |method_name|
125
+ instance_variable_set(<span class="hljs-symbol">:<span class="hljs-string">"@<span class="hljs-subst">#{method_name}</span>"</span></span>, <span class="hljs-keyword">nil</span>)
126
+ <span class="hljs-keyword">end</span>
127
+ <span class="hljs-keyword">end</span></pre></div></div>
128
+
129
+ </li>
130
+
131
+
132
+ <li id="section-5">
133
+ <div class="annotation">
134
+
135
+ <div class="pilwrap ">
136
+ <a class="pilcrow" href="#section-5">&#182;</a>
137
+ </div>
138
+ <p>All the work of generating a hash from an instance is packaged up in one method. Since
141
139
  fields can be aliases in the format <code>{ :json_key_name =&gt; :method_name }</code>, there
142
140
  is some fancy logic to determine the <code>field_name</code> and <code>method_name</code> variables.</p>
143
-
144
141
  <pre><code>{ :one =&gt; :foo }.to_a # =&gt; [[:one, :foo]]
145
- </code></pre>
146
-
147
- <p>Right now it will raise if either a field doesn&rsquo;t have a method to provide it&rsquo;s value or
142
+ </code></pre><p>Right now it will raise if either a field doesn&#39;t have a method to provide it&#39;s value or
148
143
  if there are no json fields setup for the particular set (which defaults to <code>:default</code>).</p>
149
- </td>
150
- <td class=code>
151
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">to_hash</span><span class="p">(</span><span class="nb">name</span> <span class="o">=</span> <span class="ss">:default</span><span class="p">)</span>
152
- <span class="k">if</span> <span class="n">fields</span> <span class="o">=</span> <span class="nb">self</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">json_fields</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
153
- <span class="n">fields</span><span class="o">.</span><span class="n">reduce</span><span class="p">({})</span> <span class="k">do</span> <span class="o">|</span><span class="n">memo</span><span class="p">,</span> <span class="n">field</span><span class="o">|</span>
154
- <span class="n">field_name</span><span class="p">,</span> <span class="n">method_name</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Hash</span><span class="p">)</span> <span class="p">?</span> <span class="n">field</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">first</span> <span class="p">:</span> <span class="o">[</span><span class="n">field</span><span class="p">,</span> <span class="n">field</span><span class="o">]</span>
155
- <span class="k">begin</span>
156
- <span class="n">memo</span><span class="o">[</span><span class="n">field_name</span><span class="o">]</span> <span class="o">=</span> <span class="nb">send</span><span class="p">(</span><span class="n">method_name</span><span class="p">)</span>
157
- <span class="k">rescue</span> <span class="no">NoMethodError</span> <span class="o">=&gt;</span> <span class="n">e</span>
158
- <span class="n">message</span> <span class="o">=</span> <span class="s2">&quot;There is no method named &#39;</span><span class="si">#{</span><span class="n">method_name</span><span class="si">}</span><span class="s2">&#39; for the class &#39;</span><span class="si">#{</span><span class="nb">self</span><span class="o">.</span><span class="n">class</span><span class="si">}</span><span class="s2">&#39; for the &#39;</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">&#39; list of fields : </span><span class="si">#{</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">&quot;</span>
159
- <span class="k">raise</span> <span class="no">NoMethodError</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">method_name</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
160
- <span class="k">end</span>
161
- <span class="n">memo</span>
162
- <span class="k">end</span>
163
- <span class="k">else</span>
164
- <span class="k">raise</span> <span class="s2">&quot;There are no json fields under the name: </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">&quot;</span>
165
- <span class="k">end</span>
166
- <span class="k">end</span>
167
-
168
- <span class="k">def</span> <span class="nf">to_json</span>
169
- <span class="no">JSON</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">to_hash</span><span class="p">)</span>
170
- <span class="k">end</span>
171
-
172
- <span class="k">module</span> <span class="nn">ClassMethods</span></pre></div>
173
- </td>
174
- </tr>
175
- <tr id='section-7'>
176
- <td class=docs>
177
- <div class="pilwrap">
178
- <a class="pilcrow" href="#section-7">&#182;</a>
179
- </div>
180
- <p>Defines an attr_accessor with a default value. The default for default is nil. Example:</p>
181
144
 
145
+ </div>
146
+
147
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>to_hash(name = <span class="hljs-symbol">:default</span>)
148
+ <span class="hljs-keyword">if</span> fields = <span class="hljs-keyword">self</span>.<span class="hljs-keyword">class</span>.json_fields(name)
149
+ fields.each_with_object({}) <span class="hljs-keyword">do</span> |field, memo|
150
+ field_name, method_name = field.is_a?(<span class="hljs-constant">Hash</span>) ? field.to_a.first <span class="hljs-symbol">:</span> [field, field]
151
+ <span class="hljs-keyword">if</span> <span class="hljs-keyword">self</span>.respond_to?(method_name)
152
+ memo[field_name] = send(method_name)
153
+ <span class="hljs-keyword">else</span>
154
+ message = <span class="hljs-string">"There is no method named '<span class="hljs-subst">#{method_name}</span>' for the class '<span class="hljs-subst">#{<span class="hljs-keyword">self</span>.<span class="hljs-keyword">class</span>}</span>' for the '<span class="hljs-subst">#{name}</span>' list of fields : <span class="hljs-subst">#{e.message}</span>"</span>
155
+ raise <span class="hljs-constant">NoMethodError</span>.new(message, method_name, e.args)
156
+ <span class="hljs-keyword">end</span>
157
+ <span class="hljs-keyword">end</span>
158
+ <span class="hljs-keyword">else</span>
159
+ raise <span class="hljs-string">"There are no json fields under the name: <span class="hljs-subst">#{name}</span>"</span>
160
+ <span class="hljs-keyword">end</span>
161
+ <span class="hljs-keyword">end</span>
162
+
163
+ <span class="hljs-function"><span class="hljs-keyword">def</span> </span>to_mash(name = <span class="hljs-symbol">:default</span>)
164
+ <span class="hljs-constant">Mashed::Mash</span>.new(to_hash(name))
165
+ <span class="hljs-keyword">end</span>
166
+
167
+ <span class="hljs-function"><span class="hljs-keyword">def</span> </span>to_json
168
+ <span class="hljs-constant">JSON</span>.generate(to_hash)
169
+ <span class="hljs-keyword">end</span>
170
+
171
+ <span class="hljs-class"><span class="hljs-keyword">module</span> <span class="hljs-title">ClassMethods</span></span></pre></div></div>
172
+
173
+ </li>
174
+
175
+
176
+ <li id="section-6">
177
+ <div class="annotation">
178
+
179
+ <div class="pilwrap ">
180
+ <a class="pilcrow" href="#section-6">&#182;</a>
181
+ </div>
182
+ <p>Defines an attr_accessor with a default value. The default for default is nil. Example:</p>
182
183
  <pre><code>class A
183
- register_accessor :name =&gt; "No Name"
184
+ register_accessor :name =&gt; &quot;No Name&quot;
184
185
  end
185
186
 
186
- A.new.name # =&gt; "No Name"
187
+ A.new.name # =&gt; &quot;No Name&quot;
187
188
  </code></pre>
188
- </td>
189
- <td class=code>
190
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">register_accessor</span><span class="p">(</span><span class="n">acc</span><span class="p">)</span>
191
- <span class="nb">name</span><span class="p">,</span> <span class="n">default</span> <span class="o">=</span> <span class="n">acc</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Hash</span><span class="p">)</span> <span class="p">?</span> <span class="n">acc</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">first</span> <span class="p">:</span> <span class="o">[</span><span class="n">acc</span><span class="p">,</span> <span class="kp">nil</span><span class="o">]</span>
192
- <span class="kp">attr_accessor</span> <span class="nb">name</span>
193
- <span class="k">if</span> <span class="n">default</span>
194
- <span class="n">define_method</span> <span class="nb">name</span> <span class="k">do</span>
195
- <span class="n">var_name</span> <span class="o">=</span> <span class="ss">:&quot;@</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="ss">&quot;</span>
196
- <span class="nb">instance_variable_get</span><span class="p">(</span><span class="n">var_name</span><span class="p">)</span> <span class="o">||</span> <span class="nb">instance_variable_set</span><span class="p">(</span><span class="n">var_name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span>
197
- <span class="k">end</span>
198
- <span class="k">end</span>
199
- <span class="k">end</span></pre></div>
200
- </td>
201
- </tr>
202
- <tr id='section-8'>
203
- <td class=docs>
204
- <div class="pilwrap">
205
- <a class="pilcrow" href="#section-8">&#182;</a>
206
- </div>
207
- <p>Defines an <code>#initialize</code> method that accepts a Hash argument and copies some keys out into <code>attr_accessors</code>.
208
- If your class already has an <code>#iniatialize</code> method then this will overwrite it (so don&rsquo;t use it). <code>#initialize_with</code>
189
+ </div>
190
+
191
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>register_accessor(acc)
192
+ name, default = acc.is_a?(<span class="hljs-constant">Hash</span>) ? acc.to_a.first <span class="hljs-symbol">:</span> [acc, <span class="hljs-keyword">nil</span>]
193
+ <span class="hljs-keyword">attr_accessor</span> name
194
+ <span class="hljs-keyword">if</span> default
195
+ define_method name <span class="hljs-keyword">do</span>
196
+ var_name = <span class="hljs-symbol">:<span class="hljs-string">"@<span class="hljs-subst">#{name}</span>"</span></span>
197
+ instance_variable_get(var_name) || instance_variable_set(var_name, default)
198
+ <span class="hljs-keyword">end</span>
199
+ <span class="hljs-keyword">end</span>
200
+ <span class="hljs-keyword">end</span></pre></div></div>
201
+
202
+ </li>
203
+
204
+
205
+ <li id="section-7">
206
+ <div class="annotation">
207
+
208
+ <div class="pilwrap ">
209
+ <a class="pilcrow" href="#section-7">&#182;</a>
210
+ </div>
211
+ <p>Defines an <code>#initialize</code> method that accepts a Hash argument and copies some keys out into <code>attr_accessors</code>.
212
+ If your class already has an <code>#iniatialize</code> method then this will overwrite it (so don&#39;t use it). <code>#initialize_with</code>
209
213
  does not have to be used to use any other parts of Rep.</p>
210
- </td>
211
- <td class=code>
212
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">initialize_with</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
213
- <span class="vi">@initializiation_args</span> <span class="o">=</span> <span class="n">args</span></pre></div>
214
- </td>
215
- </tr>
216
- <tr id='section-9'>
217
- <td class=docs>
218
- <div class="pilwrap">
219
- <a class="pilcrow" href="#section-9">&#182;</a>
220
- </div>
221
- <p>Remember what args we normally initialize with so we can refer to them when building shared instances.</p>
222
- </td>
223
- <td class=code>
224
- <div class='highlight'><pre> <span class="k">if</span> <span class="n">defined?</span><span class="p">(</span><span class="n">define_singleton_method</span><span class="p">)</span>
225
- <span class="n">define_singleton_method</span> <span class="ss">:initializiation_args</span> <span class="k">do</span>
226
- <span class="vi">@initializiation_args</span>
227
- <span class="k">end</span>
228
- <span class="k">else</span>
229
- <span class="n">singleton</span> <span class="o">=</span> <span class="k">class</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span><span class="p">;</span> <span class="nb">self</span> <span class="k">end</span>
230
- <span class="n">singleton</span><span class="o">.</span><span class="n">send</span> <span class="ss">:define_method</span><span class="p">,</span> <span class="ss">:initializiation_args</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="vi">@initializiation_args</span> <span class="p">}</span>
231
- <span class="k">end</span></pre></div>
232
- </td>
233
- </tr>
234
- <tr id='section-10'>
235
- <td class=docs>
236
- <div class="pilwrap">
237
- <a class="pilcrow" href="#section-10">&#182;</a>
238
- </div>
239
- <p>Create an <code>attr_accessor</code> for each one. Defaults can be provided using the Hash version { :arg => :default_value }</p>
240
- </td>
241
- <td class=code>
242
- <div class='highlight'><pre> <span class="n">args</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="n">register_accessor</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="p">}</span>
243
-
244
- <span class="n">define_method</span><span class="p">(</span><span class="ss">:initialize</span><span class="p">)</span> <span class="p">{</span> <span class="o">|*</span><span class="n">args</span><span class="o">|</span>
245
- <span class="n">opts</span> <span class="o">=</span> <span class="n">args</span><span class="o">.</span><span class="n">first</span> <span class="o">||</span> <span class="p">{}</span>
246
- <span class="n">parse_opts</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
247
- <span class="p">}</span></pre></div>
248
- </td>
249
- </tr>
250
- <tr id='section-11'>
251
- <td class=docs>
252
- <div class="pilwrap">
253
- <a class="pilcrow" href="#section-11">&#182;</a>
254
- </div>
255
- <p><code>#parse_opts</code> is responsable for getting the <code>attr_accessor</code> values prefilled. Since defaults can be specified, it
256
- must negotiate Hashes and use the first key of the hash for the <code>attr_accessor</code>&rsquo;s name.</p>
257
- </td>
258
- <td class=code>
259
- <div class='highlight'><pre> <span class="n">define_method</span> <span class="ss">:parse_opts</span> <span class="k">do</span> <span class="o">|</span><span class="n">opts</span><span class="o">|</span>
260
- <span class="vi">@rep_options</span> <span class="o">=</span> <span class="n">opts</span>
261
- <span class="nb">self</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">initializiation_args</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
262
- <span class="nb">name</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Hash</span><span class="p">)</span> <span class="p">?</span> <span class="n">field</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">first</span> <span class="p">:</span> <span class="n">field</span>
263
- <span class="nb">instance_variable_set</span><span class="p">(</span><span class="ss">:&quot;@</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="ss">&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span><span class="p">)</span>
264
- <span class="k">end</span>
265
- <span class="k">end</span>
266
- <span class="k">end</span></pre></div>
267
- </td>
268
- </tr>
269
- <tr id='section-12'>
270
- <td class=docs>
271
- <div class="pilwrap">
272
- <a class="pilcrow" href="#section-12">&#182;</a>
273
- </div>
274
- <p><code>#json_fields</code> setups up some class instance variables to remember sets of top level keys for json structures. Example:</p>
275
214
 
215
+ </div>
216
+
217
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>initialize_with(*args, &amp;blk)
218
+ <span class="hljs-variable">@initializiation_args</span> = args</pre></div></div>
219
+
220
+ </li>
221
+
222
+
223
+ <li id="section-8">
224
+ <div class="annotation">
225
+
226
+ <div class="pilwrap ">
227
+ <a class="pilcrow" href="#section-8">&#182;</a>
228
+ </div>
229
+ <p>Remember what args we normally initialize with so we can refer to them when building shared instances.</p>
230
+
231
+ </div>
232
+
233
+ <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-keyword">defined</span>?(define_singleton_method)
234
+ define_singleton_method <span class="hljs-symbol">:initializiation_args</span> <span class="hljs-keyword">do</span>
235
+ <span class="hljs-variable">@initializiation_args</span>
236
+ <span class="hljs-keyword">end</span>
237
+ <span class="hljs-keyword">else</span>
238
+ singleton = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-inheritance">&lt;</span><span class="hljs-inheritance">&lt; <span class="hljs-parent">self</span></span>;</span> <span class="hljs-keyword">self</span> <span class="hljs-keyword">end</span>
239
+ singleton.send <span class="hljs-symbol">:define_method</span>, <span class="hljs-symbol">:initializiation_args</span>, lambda { <span class="hljs-variable">@initializiation_args</span> }
240
+ <span class="hljs-keyword">end</span></pre></div></div>
241
+
242
+ </li>
243
+
244
+
245
+ <li id="section-9">
246
+ <div class="annotation">
247
+
248
+ <div class="pilwrap ">
249
+ <a class="pilcrow" href="#section-9">&#182;</a>
250
+ </div>
251
+ <p>Create an <code>attr_accessor</code> for each one. Defaults can be provided using the Hash version { :arg =&gt; :default_value }</p>
252
+
253
+ </div>
254
+
255
+ <div class="content"><div class='highlight'><pre> args.each { |a| register_accessor(a) }
256
+
257
+ define_method(<span class="hljs-symbol">:initialize</span>) { |opts={}|
258
+ parse_opts(opts)
259
+ }</pre></div></div>
260
+
261
+ </li>
262
+
263
+
264
+ <li id="section-10">
265
+ <div class="annotation">
266
+
267
+ <div class="pilwrap ">
268
+ <a class="pilcrow" href="#section-10">&#182;</a>
269
+ </div>
270
+ <p><code>#parse_opts</code> is responsable for getting the <code>attr_accessor</code> values prefilled. Since defaults can be specified, it
271
+ must negotiate Hashes and use the first key of the hash for the <code>attr_accessor</code>&#39;s name.</p>
272
+
273
+ </div>
274
+
275
+ <div class="content"><div class='highlight'><pre> define_method <span class="hljs-symbol">:parse_opts</span> <span class="hljs-keyword">do</span> |opts|
276
+ <span class="hljs-variable">@rep_options</span> = opts
277
+ blk.call(opts) <span class="hljs-keyword">unless</span> blk.<span class="hljs-keyword">nil</span>?
278
+ <span class="hljs-keyword">self</span>.<span class="hljs-keyword">class</span>.initializiation_args.each <span class="hljs-keyword">do</span> |field|
279
+ name = field.is_a?(<span class="hljs-constant">Hash</span>) ? field.to_a.first.first <span class="hljs-symbol">:</span> field
280
+ instance_variable_set(<span class="hljs-symbol">:<span class="hljs-string">"@<span class="hljs-subst">#{name}</span>"</span></span>, opts[name])
281
+ <span class="hljs-keyword">end</span>
282
+ <span class="hljs-keyword">end</span>
283
+ <span class="hljs-keyword">end</span></pre></div></div>
284
+
285
+ </li>
286
+
287
+
288
+ <li id="section-11">
289
+ <div class="annotation">
290
+
291
+ <div class="pilwrap ">
292
+ <a class="pilcrow" href="#section-11">&#182;</a>
293
+ </div>
294
+ <p><code>#json_fields</code> setups up some class instance variables to remember sets of top level keys for json structures. Example:</p>
276
295
  <pre><code>class A
277
296
  json_fields [:one, :two, :three] =&gt; :default
278
297
  end
279
298
 
280
299
  A.json_fields(:default) # =&gt; [:one, :two, :three]
281
- </code></pre>
282
-
283
- <p>There is a general assumption that each top level key&rsquo;s value is provided by a method of the same name on an instance
300
+ </code></pre><p>There is a general assumption that each top level key&#39;s value is provided by a method of the same name on an instance
284
301
  of the class. If this is not true, a Hash syntax can be used to alias to a different method name. Example:</p>
285
-
286
302
  <pre><code>class A
287
303
  json_fields [{ :one =&gt; :the_real_one_method }, :two, { :three =&gt; :some_other_three }] =&gt; :default
288
304
  end
289
- </code></pre>
290
-
291
- <p>Once can also set multiple sets of fields. Example:</p>
292
-
305
+ </code></pre><p>Once can also set multiple sets of fields. Example:</p>
293
306
  <pre><code>class A
294
307
  json_fields [:one, :two, :three] =&gt; :default
295
308
  json_fields [:five, :two, :six] =&gt; :other
296
309
  end
297
- </code></pre>
298
-
299
- <p>And all fields are returned by calling <code>#json_fields</code> with no args. Example:</p>
300
-
310
+ </code></pre><p>And all fields are returned by calling <code>#json_fields</code> with no args. Example:</p>
301
311
  <pre><code>A.json_fields # =&gt; { :default =&gt; [:one, :two, :three], :other =&gt; [:five, :two, :six] }
302
312
  </code></pre>
303
- </td>
304
- <td class=code>
305
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">json_fields</span><span class="p">(</span><span class="n">arg</span> <span class="o">=</span> <span class="kp">nil</span><span class="p">)</span>
306
- <span class="k">if</span> <span class="n">arg</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Hash</span><span class="p">)</span>
307
- <span class="n">fields</span><span class="p">,</span> <span class="nb">name</span> <span class="o">=</span> <span class="n">arg</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">first</span>
308
- <span class="vi">@json_fields</span> <span class="o">||=</span> <span class="p">{}</span>
309
- <span class="vi">@json_fields</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="o">=</span> <span class="o">[</span><span class="n">fields</span><span class="o">].</span><span class="n">flatten</span>
310
- <span class="k">elsif</span> <span class="n">arg</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Symbol</span><span class="p">)</span>
311
- <span class="vi">@json_fields</span> <span class="o">||=</span> <span class="p">{}</span>
312
- <span class="vi">@json_fields</span><span class="o">[</span><span class="n">arg</span><span class="o">]</span>
313
- <span class="k">elsif</span> <span class="n">arg</span> <span class="o">===</span> <span class="kp">nil</span>
314
- <span class="vi">@json_fields</span> <span class="o">||</span> <span class="p">{}</span>
315
- <span class="k">else</span></pre></div>
316
- </td>
317
- </tr>
318
- <tr id='section-13'>
319
- <td class=docs>
320
- <div class="pilwrap">
321
- <a class="pilcrow" href="#section-13">&#182;</a>
322
- </div>
323
- <p>TODO: make an exception class</p>
324
- </td>
325
- <td class=code>
326
- <div class='highlight'><pre> <span class="k">raise</span> <span class="s2">&quot;You can only use a Hash to set fields, a Symbol to retrieve them, or no argument to retrieve all fields for all names&quot;</span>
327
- <span class="k">end</span>
328
- <span class="k">end</span></pre></div>
329
- </td>
330
- </tr>
331
- <tr id='section-14'>
332
- <td class=docs>
333
- <div class="pilwrap">
334
- <a class="pilcrow" href="#section-14">&#182;</a>
335
- </div>
336
- <p><code>#flat_json_fields</code> is just a utility method to DRY up the next two methods, because their code is almost exactly the same,
313
+ </div>
314
+
315
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>json_fields(arg = <span class="hljs-keyword">nil</span>)
316
+ <span class="hljs-keyword">if</span> arg.is_a?(<span class="hljs-constant">Hash</span>)
317
+ fields, name = arg.to_a.first
318
+ <span class="hljs-variable">@json_fields</span> ||= {}
319
+ <span class="hljs-variable">@json_fields</span>[name] = [fields].flatten
320
+ <span class="hljs-keyword">elsif</span> arg.is_a?(<span class="hljs-constant">Symbol</span>)
321
+ <span class="hljs-variable">@json_fields</span> ||= {}
322
+ <span class="hljs-variable">@json_fields</span>[arg]
323
+ <span class="hljs-keyword">elsif</span> arg === <span class="hljs-keyword">nil</span>
324
+ <span class="hljs-variable">@json_fields</span> || {}
325
+ <span class="hljs-keyword">else</span></pre></div></div>
326
+
327
+ </li>
328
+
329
+
330
+ <li id="section-12">
331
+ <div class="annotation">
332
+
333
+ <div class="pilwrap ">
334
+ <a class="pilcrow" href="#section-12">&#182;</a>
335
+ </div>
336
+ <p>TODO: make an exception class</p>
337
+
338
+ </div>
339
+
340
+ <div class="content"><div class='highlight'><pre> raise <span class="hljs-string">"You can only use a Hash to set fields, a Symbol to retrieve them, or no argument to retrieve all fields for all names"</span>
341
+ <span class="hljs-keyword">end</span>
342
+ <span class="hljs-keyword">end</span></pre></div></div>
343
+
344
+ </li>
345
+
346
+
347
+ <li id="section-13">
348
+ <div class="annotation">
349
+
350
+ <div class="pilwrap ">
351
+ <a class="pilcrow" href="#section-13">&#182;</a>
352
+ </div>
353
+ <p><code>#flat_json_fields</code> is just a utility method to DRY up the next two methods, because their code is almost exactly the same,
337
354
  it is not intended for use directly and might be confusing.</p>
338
- </td>
339
- <td class=code>
340
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">flat_json_fields</span><span class="p">(</span><span class="n">side</span> <span class="o">=</span> <span class="ss">:right</span><span class="p">)</span>
341
- <span class="n">side_number</span> <span class="o">=</span> <span class="n">side</span> <span class="o">==</span> <span class="ss">:right</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="mi">0</span>
342
-
343
- <span class="n">json_fields</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="o">[]</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">memo</span><span class="p">,</span> <span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="n">fields</span><span class="p">)</span><span class="o">|</span>
344
- <span class="n">memo</span> <span class="o">+</span> <span class="n">fields</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
345
- <span class="k">if</span> <span class="n">field</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Hash</span><span class="p">)</span>
346
- <span class="n">field</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">first</span><span class="o">[</span><span class="n">side_number</span><span class="o">]</span> <span class="c1"># [name, method_name]</span>
347
- <span class="k">else</span>
348
- <span class="n">field</span>
349
- <span class="k">end</span>
350
- <span class="k">end</span>
351
- <span class="k">end</span><span class="o">.</span><span class="n">uniq</span>
352
- <span class="k">end</span></pre></div>
353
- </td>
354
- </tr>
355
- <tr id='section-15'>
356
- <td class=docs>
357
- <div class="pilwrap">
358
- <a class="pilcrow" href="#section-15">&#182;</a>
359
- </div>
360
- <p>We need a way to get a flat, uniq'ed list of all the fields accross all field sets. This is that.</p>
361
- </td>
362
- <td class=code>
363
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">all_json_fields</span>
364
- <span class="n">flat_json_fields</span><span class="p">(</span><span class="ss">:left</span><span class="p">)</span>
365
- <span class="k">end</span></pre></div>
366
- </td>
367
- </tr>
368
- <tr id='section-16'>
369
- <td class=docs>
370
- <div class="pilwrap">
371
- <a class="pilcrow" href="#section-16">&#182;</a>
372
- </div>
373
- <p>We need a wya to get a flat, uniq'ed list of all the method names accross all field sets. This is that.</p>
374
- </td>
375
- <td class=code>
376
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">all_json_methods</span>
377
- <span class="n">flat_json_fields</span><span class="p">(</span><span class="ss">:right</span><span class="p">)</span>
378
- <span class="k">end</span></pre></div>
379
- </td>
380
- </tr>
381
- <tr id='section-17'>
382
- <td class=docs>
383
- <div class="pilwrap">
384
- <a class="pilcrow" href="#section-17">&#182;</a>
385
- </div>
386
- <p>An easy way to save on GC is to use the same instance to turn an array of objects into hashes instead
387
- of instantiating a new object for every object in the array. Here is an example of it&rsquo;s usage:</p>
388
355
 
356
+ </div>
357
+
358
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>flat_json_fields(side = <span class="hljs-symbol">:right</span>)
359
+ side_number = side == <span class="hljs-symbol">:right</span> ? <span class="hljs-number">1</span> <span class="hljs-symbol">:</span> <span class="hljs-number">0</span>
360
+
361
+ json_fields.reduce([]) <span class="hljs-keyword">do</span> |memo, (name, fields)|
362
+ memo + fields.map <span class="hljs-keyword">do</span> |field|
363
+ <span class="hljs-keyword">if</span> field.is_a?(<span class="hljs-constant">Hash</span>)
364
+ field.to_a.first[side_number] <span class="hljs-comment"># [name, method_name]</span>
365
+ <span class="hljs-keyword">else</span>
366
+ field
367
+ <span class="hljs-keyword">end</span>
368
+ <span class="hljs-keyword">end</span>
369
+ <span class="hljs-keyword">end</span>.uniq
370
+ <span class="hljs-keyword">end</span></pre></div></div>
371
+
372
+ </li>
373
+
374
+
375
+ <li id="section-14">
376
+ <div class="annotation">
377
+
378
+ <div class="pilwrap ">
379
+ <a class="pilcrow" href="#section-14">&#182;</a>
380
+ </div>
381
+ <p>We need a way to get a flat, uniq&#39;ed list of all the fields accross all field sets. This is that.</p>
382
+
383
+ </div>
384
+
385
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>all_json_fields
386
+ flat_json_fields(<span class="hljs-symbol">:left</span>)
387
+ <span class="hljs-keyword">end</span></pre></div></div>
388
+
389
+ </li>
390
+
391
+
392
+ <li id="section-15">
393
+ <div class="annotation">
394
+
395
+ <div class="pilwrap ">
396
+ <a class="pilcrow" href="#section-15">&#182;</a>
397
+ </div>
398
+ <p>We need a wya to get a flat, uniq&#39;ed list of all the method names accross all field sets. This is that.</p>
399
+
400
+ </div>
401
+
402
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>all_json_methods
403
+ flat_json_fields(<span class="hljs-symbol">:right</span>)
404
+ <span class="hljs-keyword">end</span></pre></div></div>
405
+
406
+ </li>
407
+
408
+
409
+ <li id="section-16">
410
+ <div class="annotation">
411
+
412
+ <div class="pilwrap ">
413
+ <a class="pilcrow" href="#section-16">&#182;</a>
414
+ </div>
415
+ <p>An easy way to save on GC is to use the same instance to turn an array of objects into hashes instead
416
+ of instantiating a new object for every object in the array. Here is an example of it&#39;s usage:</p>
389
417
  <pre><code>class BookRep
390
418
  initialize_with :book_model
391
419
  fields :title =&gt; :default
392
420
  forward :title =&gt; :book_model
393
421
  end
394
422
 
395
- BookRep.shared(:book_model =&gt; Book.first).to_hash # =&gt; { :title =&gt; "Moby Dick" }
396
- BookRep.shared(:book_model =&gt; Book.last).to_hash # =&gt; { :title =&gt; "Lost Horizon" }
397
- </code></pre>
398
-
399
- <p>This should terrify you. If it doesn&rsquo;t, then this example will:</p>
400
-
423
+ BookRep.shared(:book_model =&gt; Book.first).to_hash # =&gt; { :title =&gt; &quot;Moby Dick&quot; }
424
+ BookRep.shared(:book_model =&gt; Book.last).to_hash # =&gt; { :title =&gt; &quot;Lost Horizon&quot; }
425
+ </code></pre><p>This should terrify you. If it doesn&#39;t, then this example will:</p>
401
426
  <pre><code>book1 = BookRep.shared(:book_model =&gt; Book.first)
402
427
  book2 = BookRep.shared(:book_model =&gt; Book.last)
403
428
 
404
429
  boo1.object_id === book2.object_id # =&gt; true
405
- </code></pre>
406
-
407
- <p><strong>It really is a shared object.</strong></p>
408
-
409
- <p>You really shouldn&rsquo;t use this method directly for anything.</p>
410
- </td>
411
- <td class=code>
412
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">shared</span><span class="p">(</span><span class="n">opts</span> <span class="o">=</span> <span class="p">{})</span>
413
- <span class="vi">@pointer</span> <span class="o">=</span> <span class="p">(</span><span class="no">Thread</span><span class="o">.</span><span class="n">current</span><span class="o">[</span><span class="ss">:rep_shared_instances</span><span class="o">]</span> <span class="o">||=</span> <span class="p">{})</span>
414
- <span class="vi">@pointer</span><span class="o">[</span><span class="nb">object_id</span><span class="o">]</span> <span class="o">||=</span> <span class="kp">new</span>
415
- <span class="vi">@pointer</span><span class="o">[</span><span class="nb">object_id</span><span class="o">].</span><span class="n">reset_for_json!</span>
416
- <span class="vi">@pointer</span><span class="o">[</span><span class="nb">object_id</span><span class="o">].</span><span class="n">parse_opts</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
417
- <span class="vi">@pointer</span><span class="o">[</span><span class="nb">object_id</span><span class="o">]</span>
418
- <span class="k">end</span></pre></div>
419
- </td>
420
- </tr>
421
- <tr id='section-18'>
422
- <td class=docs>
423
- <div class="pilwrap">
424
- <a class="pilcrow" href="#section-18">&#182;</a>
425
- </div>
426
- <p>The fanciest thing in this entire library is this <code>#to_proc</code> method. Here is an example of it&rsquo;s usage:</p>
427
-
430
+ </code></pre><p><strong>It really is a shared object.</strong></p>
431
+ <p>You really shouldn&#39;t use this method directly for anything.</p>
432
+
433
+ </div>
434
+
435
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>shared(opts = {})
436
+ <span class="hljs-variable">@pointer</span> = (<span class="hljs-constant">Thread</span>.current[<span class="hljs-symbol">:rep_shared_instances</span>] ||= {})
437
+ <span class="hljs-variable">@pointer</span>[object_id] ||= new
438
+ <span class="hljs-variable">@pointer</span>[object_id].reset_for_json!
439
+ <span class="hljs-variable">@pointer</span>[object_id].parse_opts(opts)
440
+ <span class="hljs-variable">@pointer</span>[object_id]
441
+ <span class="hljs-keyword">end</span></pre></div></div>
442
+
443
+ </li>
444
+
445
+
446
+ <li id="section-17">
447
+ <div class="annotation">
448
+
449
+ <div class="pilwrap ">
450
+ <a class="pilcrow" href="#section-17">&#182;</a>
451
+ </div>
452
+ <p>The fanciest thing in this entire library is this <code>#to_proc</code> method. Here is an example of it&#39;s usage:</p>
428
453
  <pre><code>class BookRep
429
454
  initialize_with :book_model
430
455
  fields :title =&gt; :default
431
456
  forward :title =&gt; :book_model
432
457
  end
433
458
 
434
- Book.all.map(&amp;BookRep) # =&gt; [{ :title =&gt; "Moby Dick" }, { :title =&gt; "Lost Horizon " }]
435
- </code></pre>
436
-
437
- <p>And now I will explain how it works. Any object can have a to_proc method and when you call <code>#map</code> on an
438
- array and hand it a proc it will in turn hand each object as an argument to that proc. What I&rsquo;ve decided
459
+ Book.all.map(&amp;BookRep) # =&gt; [{ :title =&gt; &quot;Moby Dick&quot; }, { :title =&gt; &quot;Lost Horizon &quot; }]
460
+ </code></pre><p>And now I will explain how it works. Any object can have a to_proc method and when you call <code>#map</code> on an
461
+ array and hand it a proc it will in turn hand each object as an argument to that proc. What I&#39;ve decided
439
462
  to do with this object is use it the options for a shared instance to make a hash.</p>
440
-
441
463
  <p>Since I know the different initialization argumants from a call to <code>initialize_with</code>, I can infer by order
442
464
  which object is which option. Then I can create a Hash to give to <code>parse_opts</code> through the <code>shared</code> method.
443
465
  I hope that makes sense.</p>
444
-
445
466
  <p>It allows for extremely clean Rails controllers like this:</p>
446
-
447
467
  <pre><code>class PhotosController &lt; ApplicationController
448
468
  respond_to :json, :html
449
469
 
@@ -458,27 +478,22 @@ I hope that makes sense.</p>
458
478
  end
459
479
  end
460
480
  </code></pre>
461
-
462
- </td>
463
- <td class=code>
464
- <div class='highlight'><pre> <span class="k">def</span> <span class="nf">to_proc</span>
465
- <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">obj</span><span class="o">|</span>
466
- <span class="n">arr</span> <span class="o">=</span> <span class="o">[</span><span class="n">obj</span><span class="o">].</span><span class="n">flatten</span>
467
- <span class="n">init_args</span> <span class="o">=</span> <span class="vi">@initializiation_args</span><span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="p">(</span><span class="n">arr</span><span class="o">.</span><span class="n">length</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">]</span>
468
- <span class="n">opts</span> <span class="o">=</span> <span class="no">Hash</span><span class="o">[</span><span class="n">init_args</span><span class="o">.</span><span class="n">zip</span><span class="p">(</span><span class="n">arr</span><span class="p">)</span><span class="o">]</span>
469
- <span class="n">shared</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span><span class="o">.</span><span class="n">to_hash</span>
470
- <span class="p">}</span>
471
- <span class="k">end</span>
472
- <span class="k">end</span>
473
-
474
- <span class="k">module</span> <span class="nn">MashedSupport</span>
475
- <span class="k">def</span> <span class="nf">to_hash</span><span class="p">(</span><span class="nb">name</span> <span class="o">=</span> <span class="ss">:default</span><span class="p">)</span>
476
- <span class="no">Mashed</span><span class="o">::</span><span class="no">Mash</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="k">super</span><span class="p">)</span>
477
- <span class="k">end</span>
478
- <span class="k">end</span>
479
- <span class="k">end</span></pre></div>
480
- </td>
481
- </tr>
482
- </table>
483
- </div>
481
+ </div>
482
+
483
+ <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">def</span> </span>to_proc
484
+ proc { |obj|
485
+ arr = [obj].flatten
486
+ init_args = <span class="hljs-variable">@initializiation_args</span>[<span class="hljs-number">0</span>..(arr.length-<span class="hljs-number">1</span>)]
487
+ opts = <span class="hljs-constant">Hash</span>[init_args.zip(arr)]
488
+ shared(opts).to_hash
489
+ }
490
+ <span class="hljs-keyword">end</span>
491
+ <span class="hljs-keyword">end</span>
492
+ <span class="hljs-keyword">end</span></pre></div></div>
493
+
494
+ </li>
495
+
496
+ </ul>
497
+ </div>
484
498
  </body>
499
+ </html>