arendelle 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +52 -3
- data/lib/arendelle.rb +10 -4
- metadata +3 -3
- data/arendelle.gemspec +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8c4731aa741a8c2c04710d88dd8c765def58bc0
|
4
|
+
data.tar.gz: 450779ee96a563356f0157d997c76965dd2b76ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2316e611e4cd8a45930b5071a608e154570aeb7bf31bc6516c4c2ddd13815389cc6a5052729b961f4259ea63f1754d5899942cd97b8bbf9ab239e59058c6ce1a
|
7
|
+
data.tar.gz: 7f61c21e719c80d55398c5c76622d6fee69355ffaec1383b277de9daba175846a70139e653d3d41784440fe9a6d5974916cbb57b948b47424f427831927fead6
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
## [0.1.1] - 2017-03-20
|
2
|
+
|
3
|
+
Added support for handling JSON keys that start with integers. Previously this was attempting to use an invalid instance variable ("@1234"). New behavior prepends instance variables and method access calls with an underscore: `obj._1234` or `obj.instance_variable_get("_@1234")`.
|
4
|
+
|
5
|
+
## [0.1.0] - 2017-03-06
|
6
|
+
|
7
|
+
Initial version released.
|
data/README.md
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
# Arendelle
|
2
2
|
|
3
|
-
Arendelle is a small gem with a distantly semantic name, used for initializing mostly frozen objects. If you've got kids, you probably already understand.
|
3
|
+
Arendelle is a small gem with a distantly semantic name, used for initializing mostly frozen objects. If you've got kids, you probably already understand the name.
|
4
4
|
|
5
5
|
## Why?
|
6
6
|
|
7
|
-
|
7
|
+
There are a ton of great Struct-like libraries that focus on immutable values. Some (`ure`, for example) focus on performance and offer a similar interface to Struct for declaring dynamic classes. Others give you the full kitchen sink - featuring any type of object you need, with immutability built in.
|
8
|
+
|
9
|
+
Our use case was very simple, and yet we found ourselves repeatedly reaching for the same code snippet across multiple projects. We wanted something that offers a simple interface for initializing objects when using JSON.parse (which relies on `[]=` as a setter) or something we could occasionally use as a simple set-it-and-forget-it type of simple PORO.
|
10
|
+
|
11
|
+
So we built something lightweight, optimized for our current use case: `JSON.parse(json_string, object_class: Arendelle)`. When combined with JSON.parse it builds a clean javascript-object like interface for accessing deeply nested JSON, and for us, removed any concerns about "extra" things the code was doing.
|
12
|
+
|
13
|
+
Take a look at the source for yourself: you probably don't need our help to write this gem. The surface area is incredibly small. But given the utility we've found using this lib, we figured it couldn't hurt to put it out there. So, here you go, Internet. Enjoy.
|
14
|
+
|
15
|
+
**tl;dr**
|
16
|
+
|
17
|
+
Arendelle helps prevent accidentally mutating the state of a parsed JSON file or configuration class, while providing a javascript object-like interface for accessing deeply nested settings (when used in conjunction with `JSON.parse`). See usage for more details.
|
8
18
|
|
9
19
|
## Installation
|
10
20
|
|
@@ -24,11 +34,44 @@ Or install it yourself as:
|
|
24
34
|
|
25
35
|
## Usage
|
26
36
|
|
37
|
+
```ruby
|
38
|
+
json = '{"user_settings":{"name":"Rob"}}'
|
39
|
+
obj = JSON.parse(json, object_class: Arendelle)
|
40
|
+
|
41
|
+
obj.user_settings.name
|
42
|
+
=> "Rob"
|
43
|
+
|
44
|
+
# Variables are frozen after initialization
|
45
|
+
obj.user_settings["name"] = "New Name"
|
46
|
+
=> FrozenVariableError: "Cannot modify frozen variable"
|
47
|
+
|
48
|
+
# Values are frozen after being set
|
49
|
+
name = obj.user_settings.name
|
50
|
+
name << "Test"
|
51
|
+
=> RuntimeError: "can't modify frozen String"
|
52
|
+
|
53
|
+
# We call these mostly frozen objects, because they aren't 100% immutable: they can have settings added, but not modified
|
54
|
+
newobj = Arendelle.new(key1: "value1")
|
55
|
+
newobj.key1
|
56
|
+
=> "value1"
|
57
|
+
|
58
|
+
newobj["key2"] = "value2"
|
59
|
+
newobj.key2
|
60
|
+
=> "value2"
|
61
|
+
|
62
|
+
newobj["key1"] = "value3"
|
63
|
+
=> FrozenVariableError: "Cannot modify frozen variable"
|
27
64
|
```
|
65
|
+
|
66
|
+
```yaml
|
28
67
|
# api_keys.yml
|
29
68
|
defaults: &defaults
|
30
69
|
cool_service:
|
31
70
|
client_secret: <%= ENV["COOL_SERVICE_CLIENT_SECRET"] || "default_value" %>
|
71
|
+
```
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Snippet from our "real-world" use case. For us, this is a replacement for the SettingsLogic gem.
|
32
75
|
|
33
76
|
# settings.rb
|
34
77
|
class Settings
|
@@ -48,7 +91,7 @@ class Settings
|
|
48
91
|
end
|
49
92
|
```
|
50
93
|
|
51
|
-
```
|
94
|
+
```ruby
|
52
95
|
Settings.cool_service.client_secret
|
53
96
|
=> "default_value" # assuming the ENV var isn't set
|
54
97
|
```
|
@@ -59,6 +102,12 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
59
102
|
|
60
103
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
61
104
|
|
105
|
+
## Wishlist
|
106
|
+
|
107
|
+
Currently, we're using this in conjunction with JSON.parse. In some situations, this is less than ideal, as we will rely on the recursive behavior of JSON.parse to ensure that each object is initialized appropriately - calling it as `JSON.parse({}.to_hash, object_class: Arendelle)` - which is one step too many.
|
108
|
+
|
109
|
+
Adding a `.build_from_hash` type of class method which efficiently handles recursively transforming hash isn't something we need often, but would be a nice-to-have.
|
110
|
+
|
62
111
|
## Contributing
|
63
112
|
|
64
113
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/arendelle. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
data/lib/arendelle.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
1
|
class Arendelle
|
2
|
-
VERSION = "0.1.
|
2
|
+
VERSION = "0.1.1"
|
3
3
|
|
4
4
|
def initialize(**opts)
|
5
5
|
opts.each { |k, v| self[k] = v }
|
6
6
|
end
|
7
7
|
|
8
8
|
def []=(key, value)
|
9
|
-
ivar = "
|
9
|
+
ivar = "@_#{key}"
|
10
10
|
raise FrozenVariableError if instance_variable_get(ivar)
|
11
11
|
|
12
12
|
instance_variable_set(ivar, value.freeze)
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
if key[0] =~ /\d/
|
15
|
+
define_singleton_method("_#{key}") do
|
16
|
+
instance_variable_get(ivar)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
define_singleton_method(key) do
|
20
|
+
instance_variable_get(ivar)
|
21
|
+
end
|
16
22
|
end
|
17
23
|
end
|
18
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arendelle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Cole
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -62,12 +62,12 @@ files:
|
|
62
62
|
- ".gitignore"
|
63
63
|
- ".rspec"
|
64
64
|
- ".travis.yml"
|
65
|
+
- CHANGELOG.md
|
65
66
|
- CODE_OF_CONDUCT.md
|
66
67
|
- Gemfile
|
67
68
|
- LICENSE.txt
|
68
69
|
- README.md
|
69
70
|
- Rakefile
|
70
|
-
- arendelle.gemspec
|
71
71
|
- bin/console
|
72
72
|
- bin/setup
|
73
73
|
- lib/arendelle.rb
|
data/arendelle.gemspec
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'arendelle'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "arendelle"
|
8
|
-
spec.version = Arendelle::VERSION
|
9
|
-
spec.authors = ["Rob Cole"]
|
10
|
-
spec.email = ["robcole@useed.org"]
|
11
|
-
|
12
|
-
spec.summary = %q{A simple gem for creating mostly frozen objects.
|
13
|
-
Useful for configuration-like objects.}
|
14
|
-
spec.homepage = "https://github.com/useed/arendelle"
|
15
|
-
spec.license = "MIT"
|
16
|
-
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
-
f.match(%r{^(test|spec|features)/})
|
19
|
-
end
|
20
|
-
spec.bindir = "exe"
|
21
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = ["lib"]
|
23
|
-
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.14"
|
25
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
-
end
|