bogo 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +208 -1
- data/bogo.gemspec +1 -0
- data/lib/bogo.rb +2 -1
- data/lib/bogo/lazy.rb +6 -0
- data/lib/bogo/memoization.rb +59 -5
- data/lib/bogo/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03ed553a2ed1b83be48e18aeb962196071a2bb5d
|
4
|
+
data.tar.gz: b1466ec5ade9a0317e57a4e9999d1f8448051bd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 230d6b4ca8471a43489d7abe9f1bc883c6a71f20ca1b451103b54b72e1e881fba012a6b2239468c0b6a1005e155aabae0d98886f8d2187a199c9e9cde0bb4774
|
7
|
+
data.tar.gz: 850f441d6b9e1a42f066149dbd06cd70208b3405f040a4f30939e22d9c6e54bdb284bb68f0ad8039733372310a19e364773fbf082aa993652defbc2573e9da22
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,213 @@
|
|
1
1
|
# Bogo
|
2
2
|
|
3
|
-
A collection of libraries.
|
3
|
+
A collection of helper libraries. What's in the box:
|
4
|
+
|
5
|
+
## Animal strings
|
6
|
+
|
7
|
+
Convert camel cased strings to snake case or snake cased strings
|
8
|
+
to camel case:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
require 'bogo'
|
12
|
+
|
13
|
+
class Stringer
|
14
|
+
include Bogo::AnimalStrings
|
15
|
+
end
|
16
|
+
|
17
|
+
str = Stringer.new
|
18
|
+
puts str.snake('CamelCasedString')
|
19
|
+
puts str.camel('snake_cased_string')
|
20
|
+
```
|
21
|
+
|
22
|
+
## Smash
|
23
|
+
|
24
|
+
Extension of the Hash class. It makes use of the `hashie` library and
|
25
|
+
adds a few extra features as well:
|
26
|
+
|
27
|
+
Included hashie modules:
|
28
|
+
|
29
|
+
* Hashie::Extensions::IndifferentAccess
|
30
|
+
* Hashie::Extensions::MergeInitializer
|
31
|
+
* Hashie::Extensions::DeepMerge
|
32
|
+
* Hashie::Extensions::Coercion
|
33
|
+
|
34
|
+
Added extras:
|
35
|
+
|
36
|
+
### Conversion
|
37
|
+
|
38
|
+
Will convert from `Hash` to `Smash`. This conversion includes `Hash`
|
39
|
+
types found within `Array`s:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'bogo'
|
43
|
+
|
44
|
+
inst = {:a => 1, 'b' => 2, :c => [{:z => true}]}.to_smash
|
45
|
+
puts inst[:a]
|
46
|
+
puts inst['c'].first['z']
|
47
|
+
```
|
48
|
+
|
49
|
+
and we can convert from `Smash` to `Hash` as well:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
require 'bogo'
|
53
|
+
|
54
|
+
inst = {:a => 1, 'b' => 2, :c => [{:z => true}]}.to_smash
|
55
|
+
puts inst.class
|
56
|
+
puts inst[:c].first.class
|
57
|
+
inst = inst.to_hash
|
58
|
+
puts inst.class
|
59
|
+
puts inst['c'].first.class
|
60
|
+
```
|
61
|
+
|
62
|
+
### Path Walking
|
63
|
+
|
64
|
+
Values can be returned if given a path. If the path does not exist
|
65
|
+
a `nil` will be return instead of raising an exception:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
require 'bogo'
|
69
|
+
|
70
|
+
inst = Smash.new(:a => {:b => {:c => {:d => 1}}})
|
71
|
+
puts inst.get(:a, :b, :c, :d)
|
72
|
+
puts inst.get(:a, :c, :x, :z)
|
73
|
+
```
|
74
|
+
|
75
|
+
### Default value on missing path
|
76
|
+
|
77
|
+
Use `#fetch` to provide default value if path does not exist. The
|
78
|
+
last value in the list will be used as the returned value:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
require 'bogo'
|
82
|
+
|
83
|
+
inst = Smash.new(:a => 1)
|
84
|
+
puts inst.fetch(:b, :c, 2)
|
85
|
+
```
|
86
|
+
|
87
|
+
### Set value at path
|
88
|
+
|
89
|
+
Set deeply nested values by providing the path. The last value
|
90
|
+
in the list will be set:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
require 'bogo'
|
94
|
+
|
95
|
+
inst = Smash.new
|
96
|
+
inst.set(:a, :b, :c, :d, :e, 1)
|
97
|
+
puts inst.get(:a, :b, :c, :d, :e)
|
98
|
+
```
|
99
|
+
|
100
|
+
### Checksums
|
101
|
+
|
102
|
+
Checksum will generate a new `Smash` instance with sorted keys
|
103
|
+
and then generate a SHA256 digest:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
require 'bogo'
|
107
|
+
|
108
|
+
puts Smash.new(:a => 1, :b => 2, :c => 3).checksum
|
109
|
+
puts Smash.new(:c => 3, :b => 2, :a => 1).checksum
|
110
|
+
```
|
111
|
+
|
112
|
+
## Memoization
|
113
|
+
|
114
|
+
Memoization helpers for thread and object local, thread local,
|
115
|
+
and global memoization:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
require 'bogo'
|
119
|
+
|
120
|
+
class Memo
|
121
|
+
include Bogo::Memoization
|
122
|
+
|
123
|
+
def object_value(provided_value)
|
124
|
+
memoize(:value){ provided_value }
|
125
|
+
end
|
126
|
+
|
127
|
+
def thread_value(provided_value)
|
128
|
+
memoize(:value, true){ provided_value }
|
129
|
+
end
|
130
|
+
|
131
|
+
def global_value(provided_value)
|
132
|
+
memoize(:value, :global){ provided_value }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
obj1 = Memo.new
|
137
|
+
obj2 = Memo.new
|
138
|
+
|
139
|
+
obj1.object_value('ohai')
|
140
|
+
obj1.thread_value('obai')
|
141
|
+
obj1.global_value('ohey')
|
142
|
+
|
143
|
+
puts '--- obj1 start'
|
144
|
+
puts obj1.object_value('fubar')
|
145
|
+
puts obj1.thread_value('fubar')
|
146
|
+
puts obj1.global_value('fubar')
|
147
|
+
puts '--- obj1 end'
|
148
|
+
puts '--- obj2 start'
|
149
|
+
puts obj2.object_value('fubar')
|
150
|
+
puts obj2.thread_value('fubar')
|
151
|
+
puts obj2.global_value('fubar')
|
152
|
+
puts '--- obj2 end'
|
153
|
+
|
154
|
+
## Lazy
|
155
|
+
|
156
|
+
Easily define attributes within a class. Provides
|
157
|
+
type checking, coercion, and callback integration
|
158
|
+
for dependencies and missing values.
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
require 'bogo'
|
162
|
+
|
163
|
+
class MyData
|
164
|
+
include Bogo::Lazy
|
165
|
+
|
166
|
+
attribute :name, String, :default => 'MyData'
|
167
|
+
attribute :data_id, [String, Numeric]
|
168
|
+
attribute :count, Float, :coerce => lambda{|v| v.to_f}
|
169
|
+
attribute :remote_id, Integer, :depends => :remote_loader
|
170
|
+
attribute :stuff, String
|
171
|
+
|
172
|
+
on_missing :load_things
|
173
|
+
|
174
|
+
def remote_loader
|
175
|
+
data[:remote_id] = 42
|
176
|
+
end
|
177
|
+
|
178
|
+
def load_things
|
179
|
+
data[:stuff] = 'ALL THE THINGS'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
data = MyData.new
|
184
|
+
|
185
|
+
puts data.name
|
186
|
+
data.name = 'New name!'
|
187
|
+
puts data.name
|
188
|
+
data.data_id = 1
|
189
|
+
puts data.data_id
|
190
|
+
data.data_id = 'one'
|
191
|
+
puts data.data_id
|
192
|
+
begin
|
193
|
+
data.data_id = :one
|
194
|
+
rescue TypeError => e
|
195
|
+
puts "#{e.class}: #{e}"
|
196
|
+
end
|
197
|
+
data.count = '1'
|
198
|
+
p data.count
|
199
|
+
puts data.remote_id
|
200
|
+
puts data.stuff
|
201
|
+
p data.dirty?(:name)
|
202
|
+
p data.data_id
|
203
|
+
p data.data
|
204
|
+
p data.dirty
|
205
|
+
p data.attributes
|
206
|
+
p data.dirty?
|
207
|
+
data.valid_state
|
208
|
+
p data.dirty?
|
209
|
+
p data.data
|
210
|
+
```
|
4
211
|
|
5
212
|
## Info
|
6
213
|
* Repository: https://github.com/spox/bogo
|
data/bogo.gemspec
CHANGED
data/lib/bogo.rb
CHANGED
data/lib/bogo/lazy.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'bogo'
|
2
|
+
require 'multi_json'
|
2
3
|
require 'digest/sha2'
|
3
4
|
|
4
5
|
module Bogo
|
@@ -12,6 +13,11 @@ module Bogo
|
|
12
13
|
def data
|
13
14
|
unless(@data)
|
14
15
|
@data = Smash.new
|
16
|
+
self.class.attributes.each do |key, value|
|
17
|
+
if(value.has_key?('default'))
|
18
|
+
@data[key] = value['default']
|
19
|
+
end
|
20
|
+
end
|
15
21
|
end
|
16
22
|
@data
|
17
23
|
end
|
data/lib/bogo/memoization.rb
CHANGED
@@ -4,6 +4,38 @@ module Bogo
|
|
4
4
|
# Memoization helpers
|
5
5
|
module Memoization
|
6
6
|
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Clean up isolated memoizations
|
10
|
+
#
|
11
|
+
# @param object_id [Object]
|
12
|
+
# @return [Proc]
|
13
|
+
def cleanup(object_id)
|
14
|
+
proc do
|
15
|
+
Thread.current[:bogo_memoization].delete_if do |k,v|
|
16
|
+
k.to_s.start_with?(object_id.to_s)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Clear thread memoizations
|
22
|
+
#
|
23
|
+
# @return [nil]
|
24
|
+
def clear_current!
|
25
|
+
Thread.current[:bogo_memoization] = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
# Clear global memoizations
|
29
|
+
#
|
30
|
+
# @return [nil]
|
31
|
+
def clear_global!
|
32
|
+
Thread.exclusive do
|
33
|
+
$bogo_memoization = Smash.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
7
39
|
# Memoize data
|
8
40
|
#
|
9
41
|
# @param key [String, Symbol] identifier for data
|
@@ -15,14 +47,29 @@ module Bogo
|
|
15
47
|
unless(direct)
|
16
48
|
key = "#{self.object_id}_#{key}"
|
17
49
|
end
|
18
|
-
|
19
|
-
|
50
|
+
if(direct == :global)
|
51
|
+
Thread.exclusive do
|
52
|
+
$bogo_memoization ||= Smash.new
|
53
|
+
unless($bogo_memoization.has_key?(key))
|
54
|
+
$bogo_memoization[key] = yield
|
55
|
+
end
|
56
|
+
$bogo_memoization[key]
|
57
|
+
end
|
58
|
+
else
|
59
|
+
unless(_memo.has_key?(key))
|
60
|
+
_memo[key] = yield
|
61
|
+
end
|
62
|
+
_memo[key]
|
20
63
|
end
|
21
|
-
_memo[key]
|
22
64
|
end
|
23
65
|
|
66
|
+
# @return [Smash] memoization hash for current thread
|
24
67
|
def _memo
|
25
|
-
Thread.current[:bogo_memoization]
|
68
|
+
unless(Thread.current[:bogo_memoization])
|
69
|
+
Thread.current[:bogo_memoization] = Smash.new
|
70
|
+
ObjectSpace.define_finalizer(self, Bogo::Memoization.cleanup(self.object_id))
|
71
|
+
end
|
72
|
+
Thread.current[:bogo_memoization]
|
26
73
|
end
|
27
74
|
|
28
75
|
# Remove memoized value
|
@@ -34,7 +81,14 @@ module Bogo
|
|
34
81
|
unless(direct)
|
35
82
|
key = "#{self.object_id}_#{key}"
|
36
83
|
end
|
37
|
-
|
84
|
+
if(direct == :global)
|
85
|
+
Thread.exclusive do
|
86
|
+
$bogo_memoization ||= Smash.new
|
87
|
+
$bogo_memoization.delete(key)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
_memo.delete(key)
|
91
|
+
end
|
38
92
|
end
|
39
93
|
|
40
94
|
# Remove all memoized values
|
data/lib/bogo/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bogo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
description: Helper libraries
|
28
42
|
email: code@chrisroberts.org
|
29
43
|
executables: []
|