static-struct 0.1.4 → 0.1.5
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/README.md +35 -2
- data/lib/static-struct.rb +1 -0
- data/lib/static_struct/structure.rb +11 -11
- data/lib/static_struct/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82798250f06d7fb357a049c10b48f54dc1a02416
|
4
|
+
data.tar.gz: 28616d06bb7579ddfd4faf15bd5f1c49114786c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18637a10c2787c7639dacbb7aa5794752145cf4d1398cec4fd929c99e0ffe1a31404936706dc15e0301a700710a4982e4f5a9828d35c795914deb5e271fabfbc
|
7
|
+
data.tar.gz: 08536c69db61880fb9451361e5a6f3e9b181bb038552108a891506612fe1cdf584781c0de2a36f27c933e17502327b208c74ae0e8899b59b523afe8e17d1df3b
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Convert Ruby hashes (or hash-like objects) into Ruby objects.
|
|
6
6
|
|
7
7
|
Key features:
|
8
8
|
|
9
|
-
* Nesting hashes and respond to objects `to_hash` methods are allowed to do the
|
9
|
+
* Nesting hashes and respond to objects `to_hash` methods are allowed to do the conversation;
|
10
10
|
* There are no limitations of the nesting;
|
11
11
|
* It is not possible to call undefined methods;
|
12
12
|
* The defined dynamically structure is iterable (responds to `each`);
|
@@ -14,7 +14,7 @@ Key features:
|
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
17
|
-
Add this line to your application's Gemfile
|
17
|
+
Add this line to your application's `Gemfile`:
|
18
18
|
|
19
19
|
```ruby
|
20
20
|
gem 'static-struct', require 'static_struct'
|
@@ -52,6 +52,39 @@ struct.enum_for(:each).map do |key, val|
|
|
52
52
|
end # => [["foo", "bar"], ["foo_foo", #<Enumerator: #<StaticStruct::Structure foo = bar>:each>]]
|
53
53
|
```
|
54
54
|
|
55
|
+
## Motivation
|
56
|
+
|
57
|
+
What the problem solves the gem? Well, it's very straightforward to explain. Lately we are facing the issues
|
58
|
+
that covert Ruby objects into JSON in order to respond it to the client more often. It's rather easy task
|
59
|
+
and may be solved without any third-party libraries. Commonly the Ruby objects are transformed into
|
60
|
+
`Hash`'es and then - into JSON. The client side receives the formed JSON and in JavaScript (as usual)
|
61
|
+
we are free to use the JSON properties via `.` call (`{foo: 'bar'}` can be called as `foo.bar`).
|
62
|
+
|
63
|
+
Getting properties via `.` notation is more convenient in JavaScript versus getting them via `[]`.
|
64
|
+
But in Ruby it's more robust and safe in addition to the convenience. That means, it's not possible
|
65
|
+
to call undefined methods in Ruby. We just get exceptions with well explained messages in such cases.
|
66
|
+
And this is cool - having early exceptions in our Ruby code makes application bug free, allows to
|
67
|
+
reduce debugging time when something goes wrong. As more code with incorrect state we have in Ruby as
|
68
|
+
more we spend time in debugging. But debugging Ruby code is awful and should be reduced.
|
69
|
+
|
70
|
+
Ok, we have peace of code on the server side that generates `Hash` with necessary structure for the client side.
|
71
|
+
But later we need to send emails based on the same structure as the client renders `HTML`. Commonly
|
72
|
+
emails are rendered on the server side and that means that we have a dilemma here: from one side we
|
73
|
+
could use the generated `Hash` there but this is not a convenient and robust solution as we already
|
74
|
+
figured out; from other side we could transform the `Hash` into a Ruby objects structure, that's
|
75
|
+
correct solution but the problem is that there is no a good ready library for this. So, here this gem comes
|
76
|
+
to the help. It allows to create a robust Ruby objects structure given the `Hash`.
|
77
|
+
|
78
|
+
Others say that we could use [ostruct](http://ruby-doc.org/stdlib-2.0.0/libdoc/ostruct/rdoc/OpenStruct.html) or [hashie](https://github.com/intridea/hashie) in order to solve the problem. But they don't solve one
|
79
|
+
important issue - when there is no defined property on the structure there should be an **exception**.
|
80
|
+
Only this way we make a profit reducing bugs and debugging time.
|
81
|
+
|
82
|
+
As you noticed the library creates an immutable Ruby objects structure, all the state is holding
|
83
|
+
in methods, there are no variables for the generating methods. This is made intentionally in order to
|
84
|
+
reduce having incorrect states of the generated Ruby structure. As you see the structure is assumed
|
85
|
+
to be used only for read-only purpose. But if you have some circumstances where we need to change the
|
86
|
+
state feel free to open an issue for the discussion.
|
87
|
+
|
55
88
|
## Development
|
56
89
|
|
57
90
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'static_struct'
|
@@ -6,7 +6,7 @@ module StaticStruct
|
|
6
6
|
|
7
7
|
def initialize(hash)
|
8
8
|
@static_methods = SortedSet.new
|
9
|
-
define_structure(
|
9
|
+
define_structure(hash)
|
10
10
|
end
|
11
11
|
|
12
12
|
def to_s
|
@@ -41,21 +41,21 @@ module StaticStruct
|
|
41
41
|
|
42
42
|
private
|
43
43
|
|
44
|
-
def define_structure(
|
44
|
+
def define_structure(hash)
|
45
45
|
Hash(hash).each do |key, val|
|
46
|
-
safe_define_method(
|
46
|
+
safe_define_method(key, val)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def safe_define_method(
|
51
|
-
if
|
52
|
-
fail MethodAlreadyDefinedError, "`#{method}' is already defined for #{
|
50
|
+
def safe_define_method(method, return_value)
|
51
|
+
if respond_to?(method)
|
52
|
+
fail MethodAlreadyDefinedError, "`#{method}' is already defined for #{self}"
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
static_methods.add(method.to_s)
|
56
56
|
case
|
57
57
|
when return_value.is_a?(Array)
|
58
|
-
|
58
|
+
define_singleton_method(method) do
|
59
59
|
return_value.map do |array_value|
|
60
60
|
if array_value.respond_to?(:to_hash)
|
61
61
|
Structure.new(array_value)
|
@@ -65,11 +65,11 @@ module StaticStruct
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
when return_value.is_a?(Hash)
|
68
|
-
|
68
|
+
define_singleton_method(method) { Structure.new(return_value) }
|
69
69
|
when return_value.respond_to?(:to_hash)
|
70
|
-
|
70
|
+
define_singleton_method(method) { Structure.new(Hash(return_value)) }
|
71
71
|
else
|
72
|
-
|
72
|
+
define_singleton_method(method) { return_value }
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: static-struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mezuka LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- Rakefile
|
71
71
|
- bin/console
|
72
72
|
- bin/setup
|
73
|
+
- lib/static-struct.rb
|
73
74
|
- lib/static_struct.rb
|
74
75
|
- lib/static_struct/method_already_defined_error.rb
|
75
76
|
- lib/static_struct/structure.rb
|