static-struct 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|