rep 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +11 -0
- data/README.md +8 -14
- data/Rakefile +18 -1
- data/docs/index.html +478 -0
- data/docs/lib/rep.html +478 -0
- data/docs/lib/rep/version.html +44 -0
- data/docs/rep.html +478 -0
- data/docs/rep/version.html +44 -0
- data/lib/rep.rb +180 -16
- data/lib/rep/version.rb +1 -1
- data/rep.gemspec +4 -0
- data/test/lib/rep_test.rb +47 -13
- data/test/test_helper.rb +0 -6
- metadata +72 -2
@@ -0,0 +1,44 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>version.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
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="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>version.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">¶</a>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
|
35
|
+
</td>
|
36
|
+
<td class=code>
|
37
|
+
<div class='highlight'><pre><span class="k">module</span> <span class="nn">Rep</span>
|
38
|
+
<span class="no">VERSION</span> <span class="o">=</span> <span class="s2">"0.0.1"</span>
|
39
|
+
<span class="k">end</span></pre></div>
|
40
|
+
</td>
|
41
|
+
</tr>
|
42
|
+
</table>
|
43
|
+
</div>
|
44
|
+
</body>
|
data/lib/rep.rb
CHANGED
@@ -1,13 +1,51 @@
|
|
1
|
-
|
1
|
+
# **Rep** is a small module to endow any class to make json quickly. It solves four problems:
|
2
|
+
#
|
3
|
+
# 1. Enumerating top level keys for a json structure
|
4
|
+
# 2. Providing a convention for the value of those keys
|
5
|
+
# 3. Defining `attr_accessor`'s that are prefilled from an options hash given to `#initialize`
|
6
|
+
# 4. Sharing instances to help GC
|
7
|
+
#
|
8
|
+
# The code is available on [github](http://github.com/myobie/rep).
|
9
|
+
|
10
|
+
# `Forwardable` is in the stdlib and allows ruby objects to delegate methods off to other objects. An example:
|
11
|
+
#
|
12
|
+
# class A
|
13
|
+
# extend Forwardable
|
14
|
+
# delegate [:length, :first] => :@array
|
15
|
+
# def initialize(array = [])
|
16
|
+
# @array = array
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# A.new([1,2,3]).length # => 3
|
21
|
+
# A.new([1,2,3]).first # => 1
|
22
|
+
|
2
23
|
require 'forwardable'
|
24
|
+
|
25
|
+
# `JSON::generate` and `JSON::decode` are much safer to use than `Object#to_json`.
|
26
|
+
|
3
27
|
require 'json'
|
4
28
|
|
29
|
+
require 'rep/version'
|
5
30
|
module Rep
|
31
|
+
|
32
|
+
# All classes that `include Rep` are extended with `Forwardable`,
|
33
|
+
# given some aliases, endowned with `HashieSupport` if Hashie is loaded,
|
34
|
+
# and given a delegate method if it doesn't already have one.
|
35
|
+
|
6
36
|
def self.included(klass)
|
7
37
|
klass.extend Forwardable
|
8
38
|
klass.extend ClassMethods
|
9
39
|
klass.instance_eval {
|
10
40
|
class << self
|
41
|
+
unless defined?(delegate)
|
42
|
+
def delegate(opts = {})
|
43
|
+
methods, object_name = opts.to_a.first
|
44
|
+
args = [object_name, methods].flatten
|
45
|
+
def_delegators *args
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
11
49
|
alias forward delegate
|
12
50
|
|
13
51
|
unless defined?(fields)
|
@@ -18,21 +56,29 @@ module Rep
|
|
18
56
|
include HashieSupport
|
19
57
|
end
|
20
58
|
end
|
21
|
-
|
22
|
-
unless defined?(parse_opts)
|
23
|
-
def parse_opts(opts = {})
|
24
|
-
# NOOP
|
25
|
-
end
|
26
|
-
end
|
27
59
|
}
|
28
60
|
end
|
29
61
|
|
62
|
+
# Since a goal is to be able to share instances, we need an easy way to reset a
|
63
|
+
# shared instance back to factory defaults. If you memoize any methods that are
|
64
|
+
# not declared as json fields, then overried this method and set any memoized
|
65
|
+
# variables to nil, then super.
|
66
|
+
|
30
67
|
def reset_for_json!
|
31
68
|
self.class.all_json_methods.each do |method_name|
|
32
69
|
instance_variable_set(:"@#{method_name}", nil)
|
33
70
|
end
|
34
71
|
end
|
35
72
|
|
73
|
+
# All the work of generating a hash from an instance is packaged up in one method. Since
|
74
|
+
# fields can be aliases in the format `{ :json_key_name => :method_name }`, there
|
75
|
+
# is some fancy logic to determine the `field_name` and `method_name` variables.
|
76
|
+
#
|
77
|
+
# { :one => :foo }.to_a # => [[:one, :foo]]
|
78
|
+
#
|
79
|
+
# Right now it will raise if either a field doesn't have a method to provide it's value or
|
80
|
+
# if there are no json fields setup for the particular set (which defaults to `:default`).
|
81
|
+
|
36
82
|
def to_hash(name = :default)
|
37
83
|
if fields = self.class.json_fields(name)
|
38
84
|
fields.reduce({}) do |memo, field|
|
@@ -55,6 +101,15 @@ module Rep
|
|
55
101
|
end
|
56
102
|
|
57
103
|
module ClassMethods
|
104
|
+
|
105
|
+
# Defines an attr_accessor with a default value. The default for default is nil. Example:
|
106
|
+
#
|
107
|
+
# class A
|
108
|
+
# register_accessor :name => "No Name"
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# A.new.name # => "No Name"
|
112
|
+
|
58
113
|
def register_accessor(acc)
|
59
114
|
name, default = acc.is_a?(Hash) ? acc.to_a.first : [acc, nil]
|
60
115
|
attr_accessor name
|
@@ -66,19 +121,38 @@ module Rep
|
|
66
121
|
end
|
67
122
|
end
|
68
123
|
|
124
|
+
# Defines an `#initialize` method that accepts a Hash argument and copies some keys out into `attr_accessors`.
|
125
|
+
# If your class already has an `#iniatialize` method then this will overwrite it (so don't use it). `#initialize_with`
|
126
|
+
# does not have to be used to use any other parts of Rep.
|
127
|
+
|
69
128
|
def initialize_with(*args)
|
70
129
|
@initializiation_args = args
|
71
130
|
|
72
|
-
|
73
|
-
|
131
|
+
# Remember what args we normally initialize with so we can refer to them when building shared instances.
|
132
|
+
|
133
|
+
if defined?(define_singleton_method)
|
134
|
+
define_singleton_method :initializiation_args do
|
135
|
+
@initializiation_args
|
136
|
+
end
|
137
|
+
else
|
138
|
+
singleton = class << self; self end
|
139
|
+
singleton.send :define_method, :initializiation_args, lambda { @initializiation_args }
|
74
140
|
end
|
75
141
|
|
142
|
+
# Create an `attr_accessor` for each one. Defaults can be provided using the Hash version { :arg => :default_value }
|
143
|
+
|
76
144
|
args.each { |a| register_accessor(a) }
|
77
145
|
|
78
|
-
define_method(:initialize) { |
|
146
|
+
define_method(:initialize) { |*args|
|
147
|
+
opts = args.first || {}
|
148
|
+
parse_opts(opts)
|
149
|
+
}
|
150
|
+
|
151
|
+
# `#parse_opts` is responsable for getting the `attr_accessor` values prefilled. Since defaults can be specified, it
|
152
|
+
# must negotiate Hashes and use the first key of the hash for the `attr_accessor`'s name.
|
79
153
|
|
80
154
|
define_method :parse_opts do |opts|
|
81
|
-
@
|
155
|
+
@rep_options = opts
|
82
156
|
self.class.initializiation_args.each do |field|
|
83
157
|
name = field.is_a?(Hash) ? field.to_a.first.first : field
|
84
158
|
instance_variable_set(:"@#{name}", opts[name])
|
@@ -86,6 +160,32 @@ module Rep
|
|
86
160
|
end
|
87
161
|
end
|
88
162
|
|
163
|
+
# `#json_fields` setups up some class instance variables to remember sets of top level keys for json structures. Example:
|
164
|
+
#
|
165
|
+
# class A
|
166
|
+
# json_fields [:one, :two, :three] => :default
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# A.json_fields(:default) # => [:one, :two, :three]
|
170
|
+
#
|
171
|
+
# There is a general assumption that each top level key's value is provided by a method of the same name on an instance
|
172
|
+
# of the class. If this is not true, a Hash syntax can be used to alias to a different method name. Example:
|
173
|
+
#
|
174
|
+
# class A
|
175
|
+
# json_fields [{ :one => :the_real_one_method }, :two, { :three => :some_other_three }] => :default
|
176
|
+
# end
|
177
|
+
#
|
178
|
+
# Once can also set multiple sets of fields. Example:
|
179
|
+
#
|
180
|
+
# class A
|
181
|
+
# json_fields [:one, :two, :three] => :default
|
182
|
+
# json_fields [:five, :two, :six] => :other
|
183
|
+
# end
|
184
|
+
#
|
185
|
+
# And all fields are returned by calling `#json_fields` with no args. Example:
|
186
|
+
#
|
187
|
+
# A.json_fields # => { :default => [:one, :two, :three], :other => [:five, :two, :six] }
|
188
|
+
|
89
189
|
def json_fields(arg = nil)
|
90
190
|
if arg.is_a?(Hash)
|
91
191
|
fields, name = arg.to_a.first
|
@@ -102,6 +202,9 @@ module Rep
|
|
102
202
|
end
|
103
203
|
end
|
104
204
|
|
205
|
+
# `#flat_json_fields` is just a utility method to DRY up the next two methods, because their code is almost exactly the same,
|
206
|
+
# it is not intended for use directly and might be confusing.
|
207
|
+
|
105
208
|
def flat_json_fields(side = :right)
|
106
209
|
side_number = side == :right ? 1 : 0
|
107
210
|
|
@@ -116,22 +219,83 @@ module Rep
|
|
116
219
|
end.uniq
|
117
220
|
end
|
118
221
|
|
222
|
+
# We need a way to get a flat, uniq'ed list of all the fields accross all field sets. This is that.
|
223
|
+
|
119
224
|
def all_json_fields
|
120
225
|
flat_json_fields(:left)
|
121
226
|
end
|
122
227
|
|
228
|
+
# We need a wya to get a flat, uniq'ed list of all the method names accross all field sets. This is that.
|
229
|
+
|
123
230
|
def all_json_methods
|
124
231
|
flat_json_fields(:right)
|
125
232
|
end
|
126
233
|
|
127
|
-
#
|
234
|
+
# An easy way to save on GC is to use the same instance to turn an array of objects into hashes instead
|
235
|
+
# of instantiating a new object for every object in the array. Here is an example of it's usage:
|
236
|
+
#
|
237
|
+
# class BookRep
|
238
|
+
# initialize_with :book_model
|
239
|
+
# fields :title => :default
|
240
|
+
# forward :title => :book_model
|
241
|
+
# end
|
242
|
+
#
|
243
|
+
# BookRep.shared(:book_model => Book.first).to_hash # => { :title => "Moby Dick" }
|
244
|
+
# BookRep.shared(:book_model => Book.last).to_hash # => { :title => "Lost Horizon" }
|
245
|
+
#
|
246
|
+
# This should terrify you. If it doesn't, then this example will:
|
247
|
+
#
|
248
|
+
# book1 = BookRep.shared(:book_model => Book.first)
|
249
|
+
# book2 = BookRep.shared(:book_model => Book.last)
|
250
|
+
#
|
251
|
+
# boo1.object_id === book2.object_id # => true
|
252
|
+
#
|
253
|
+
# **It really is a shared object.**
|
254
|
+
#
|
255
|
+
# You really shouldn't use this method directly for anything.
|
256
|
+
|
128
257
|
def shared(opts = {})
|
129
|
-
@
|
130
|
-
@
|
131
|
-
@
|
132
|
-
@
|
258
|
+
@pointer = (Thread.current[:rep_shared_instances] ||= {})
|
259
|
+
@pointer[object_id] ||= new
|
260
|
+
@pointer[object_id].reset_for_json!
|
261
|
+
@pointer[object_id].parse_opts(opts)
|
262
|
+
@pointer[object_id]
|
133
263
|
end
|
134
264
|
|
265
|
+
# The fanciest thing in this entire library is this `#to_proc` method. Here is an example of it's usage:
|
266
|
+
#
|
267
|
+
# class BookRep
|
268
|
+
# initialize_with :book_model
|
269
|
+
# fields :title => :default
|
270
|
+
# forward :title => :book_model
|
271
|
+
# end
|
272
|
+
#
|
273
|
+
# Book.all.map(&BookRep) # => [{ :title => "Moby Dick" }, { :title => "Lost Horizon " }]
|
274
|
+
#
|
275
|
+
# And now I will explain how it works. Any object can have a to_proc method and when you call `#map` on an
|
276
|
+
# array and hand it a proc it will in turn hand each object as an argument to that proc. What I've decided
|
277
|
+
# to do with this object is use it the options for a shared instance to make a hash.
|
278
|
+
#
|
279
|
+
# Since I know the different initialization argumants from a call to `initialize_with`, I can infer by order
|
280
|
+
# which object is which option. Then I can create a Hash to give to `parse_opts` through the `shared` method.
|
281
|
+
# I hope that makes sense.
|
282
|
+
#
|
283
|
+
# It allows for extremely clean Rails controllers like this:
|
284
|
+
#
|
285
|
+
# class PhotosController < ApplicationController
|
286
|
+
# respond_to :json, :html
|
287
|
+
#
|
288
|
+
# def index
|
289
|
+
# @photos = Photo.paginate(page: params[:page], per_page: 20)
|
290
|
+
# respond_with @photos.map(&PhotoRep)
|
291
|
+
# end
|
292
|
+
#
|
293
|
+
# def show
|
294
|
+
# @photo = Photo.find(params[:id])
|
295
|
+
# respond_with PhotoRep.new(photo: @photo)
|
296
|
+
# end
|
297
|
+
# end
|
298
|
+
|
135
299
|
def to_proc
|
136
300
|
proc { |obj|
|
137
301
|
arr = [obj].flatten
|
data/lib/rep/version.rb
CHANGED
data/rep.gemspec
CHANGED
@@ -17,4 +17,8 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
gem.add_dependency 'json'
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'minitest'
|
22
|
+
gem.add_development_dependency 'rocco'
|
23
|
+
gem.add_development_dependency 'rdiscount'
|
20
24
|
end
|
data/test/lib/rep_test.rb
CHANGED
@@ -23,10 +23,6 @@ describe Rep do
|
|
23
23
|
new_rep_class.must_respond_to :fields
|
24
24
|
end
|
25
25
|
|
26
|
-
it "has a parse_opts method" do
|
27
|
-
new_rep_class.must_respond_to :parse_opts
|
28
|
-
end
|
29
|
-
|
30
26
|
it "can have fields" do
|
31
27
|
klass = new_rep_class do
|
32
28
|
fields [:foo, :bar] => :default
|
@@ -38,24 +34,24 @@ describe Rep do
|
|
38
34
|
klass = new_rep_class do
|
39
35
|
initialize_with :foo, :bar
|
40
36
|
end
|
41
|
-
inst = klass.new(foo
|
37
|
+
inst = klass.new(:foo => 'foo123')
|
42
38
|
inst.foo.must_equal 'foo123'
|
43
39
|
inst.bar.must_be_nil
|
44
40
|
end
|
45
41
|
|
46
42
|
it "can have default initialization options" do
|
47
43
|
klass = new_rep_class do
|
48
|
-
initialize_with :foo, { bar
|
44
|
+
initialize_with :foo, { :bar => "barbar" }
|
49
45
|
end
|
50
|
-
inst = klass.new(foo
|
46
|
+
inst = klass.new(:foo => 'foofoo')
|
51
47
|
inst.bar.must_equal 'barbar'
|
52
48
|
end
|
53
49
|
|
54
50
|
it "can overried default initialization options" do
|
55
51
|
klass = new_rep_class do
|
56
|
-
initialize_with :foo, { bar
|
52
|
+
initialize_with :foo, { :bar => "barbar" }
|
57
53
|
end
|
58
|
-
inst = klass.new(bar
|
54
|
+
inst = klass.new(:bar => 'notbar')
|
59
55
|
inst.bar.must_equal 'notbar'
|
60
56
|
inst.foo.must_be_nil
|
61
57
|
end
|
@@ -84,7 +80,7 @@ describe Rep do
|
|
84
80
|
def two; 2; end
|
85
81
|
def three; 3; end
|
86
82
|
end
|
87
|
-
klass.new.to_hash.must_equal one
|
83
|
+
klass.new.to_hash.must_equal :one => 1, :two => 2, :three => 3
|
88
84
|
end
|
89
85
|
|
90
86
|
it "should send fields to instance to make json" do
|
@@ -133,10 +129,48 @@ describe Rep do
|
|
133
129
|
fields :keys => :default
|
134
130
|
forward :keys => :hash
|
135
131
|
end
|
136
|
-
hashes = [{ one
|
137
|
-
{ three
|
138
|
-
{ one
|
132
|
+
hashes = [{ :one => 1, :two => 2 },
|
133
|
+
{ :three => 3, :four => 4 },
|
134
|
+
{ :one => 1, :five => 5 }]
|
139
135
|
hashes.map(&klass).to_json.must_equal '[{"keys":["one","two"]},{"keys":["three","four"]},{"keys":["one","five"]}]'
|
140
136
|
end
|
141
137
|
|
138
|
+
describe "shared" do
|
139
|
+
|
140
|
+
User = Struct.new(:name, :age)
|
141
|
+
def users
|
142
|
+
@users ||= %w(Nathan 28 Jason 31 Justin 23).each_slice(2).
|
143
|
+
map { |name, age| User.new(name, age.to_i) }
|
144
|
+
end
|
145
|
+
class UserRep
|
146
|
+
include Rep
|
147
|
+
initialize_with :user
|
148
|
+
fields [:name, :age, :random_number] => :default
|
149
|
+
forward fields(:default) => :user
|
150
|
+
|
151
|
+
def random_number
|
152
|
+
@random_number ||= rand(100)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should memoize random_number" do
|
157
|
+
rep = UserRep.new(:user => users.first)
|
158
|
+
rep.random_number.must_equal rep.random_number
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should get a clean instance each time" do
|
162
|
+
num1 = UserRep.shared(:user => users.first).random_number
|
163
|
+
num2 = UserRep.shared(:user => users.first).random_number
|
164
|
+
num1.wont_equal num2
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should be really really shared" do
|
168
|
+
rep1 = UserRep.shared(:user => users.first)
|
169
|
+
rep2 = UserRep.shared(:user => users.last)
|
170
|
+
rep1.must_equal rep2
|
171
|
+
rep1.name.must_equal rep2.name
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
142
176
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -27,6 +27,70 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: minitest
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rocco
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rdiscount
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
30
94
|
description: A library for writing authoritative representations of objects for pages
|
31
95
|
and apis.
|
32
96
|
email:
|
@@ -36,10 +100,16 @@ extensions: []
|
|
36
100
|
extra_rdoc_files: []
|
37
101
|
files:
|
38
102
|
- .gitignore
|
103
|
+
- .travis.yml
|
39
104
|
- Gemfile
|
40
105
|
- LICENSE.txt
|
41
106
|
- README.md
|
42
107
|
- Rakefile
|
108
|
+
- docs/index.html
|
109
|
+
- docs/lib/rep.html
|
110
|
+
- docs/lib/rep/version.html
|
111
|
+
- docs/rep.html
|
112
|
+
- docs/rep/version.html
|
43
113
|
- lib/rep.rb
|
44
114
|
- lib/rep/version.rb
|
45
115
|
- rep.gemspec
|