sd_struct 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db8247a8652fb98a73e935ce9c0737d3bcb60aeb
4
- data.tar.gz: e681ebbbe672b041dbe2d84e7e819123c7bfd966
3
+ metadata.gz: 3b7a67f6e73b67288c75959f12b9c28557326ef7
4
+ data.tar.gz: 0e4dc23fda1637c672516f58aad9e79e8492b1b9
5
5
  SHA512:
6
- metadata.gz: a46da494946f552eca4dc1912c1d6f96667f933539b9fe4f66d37f530600f52e6e508c7a9c26a4d541f71c433af85dd890008bef1b231af98fe8d30878027b03
7
- data.tar.gz: 3987632b1425ef16c1535a740ac68183170a644b9b1122e14ac3e2eab9c9d24c6745c357e957e5fe2266ef452f9a8a172e7bd097afeb9f8c5b2ab96b7c942837
6
+ metadata.gz: 1ac85d00a9d591074e27c9174cfb100cbdb220752060b8f811bf5c0d71d4acb357f91eef2bd7f6480c8b8529be51720898dd1e2d055b430d0be6a935fffa35c6
7
+ data.tar.gz: 58fa6f524bde91f41511e78d561eb829e746d8564965c136bf91c8462b5c4cdd835889a79894e4b41b43a00fdfc8f86a568affdb63dfc7d250d478de415bd2a6
data/README.md CHANGED
@@ -71,13 +71,13 @@ sd_struct.to_h
71
71
  ```
72
72
 
73
73
 
74
- > OpenStruct uses `method_missing` to create new field, while SDStruct prevent creation
75
- > of new field using dot notation.
74
+ > OpenStruct allows creation of a new field with dot notation while SDStruct
75
+ > prevents it
76
76
 
77
- SDStruct prevent creation of new field using dot notation once it is initialized
78
- to prevent assigning unintended field when you mistyped the key/field. SDStruct
79
- is stricter in that way. However, SDStruct can also be lenient. You can use
80
- square brackets when you want to assign a new field.
77
+ SDStruct disallows creation of a new field using dot notation to prevent
78
+ assigning unintended field when you mistyped the key/field. SDStruct is
79
+ stricter in that way. However, SDStruct can also be lenient. You can use square
80
+ brackets when you want to assign a new field.
81
81
 
82
82
  ```ruby
83
83
  ## OpenStruct
@@ -114,10 +114,10 @@ sd_struct.find('/array/0/one')
114
114
  sd_struct.find('object->a', separator: '->')
115
115
  # => "bau bau"
116
116
 
117
+ # You can push it to find deeper. It will return the first occurrence of the matched field
117
118
  sd_struct.find('.array..one', separator: '.')
118
119
  # => 1
119
120
 
120
- # You can push it to find deeper. It will return the first occurrence of the matched field
121
121
  sd_struct.find('//a')
122
122
  # => "bau bau"
123
123
 
@@ -274,6 +274,19 @@ that doesn't have deep search and deep convert capabilities.
274
274
  require 'sd_struct/base'
275
275
  ```
276
276
 
277
+ ## Attribution
278
+
279
+ OpenStruct is used as the base of this project.
280
+
281
+
282
+ ## TODO
283
+
284
+ * Add specs
285
+ * Add `method_missing` to define singleton method when a field/member/key is
286
+ called (and not during initialization) to execute initialization faster
287
+ * Reimplement SDStruct to extend Hash (possibly will make it faster)
288
+
289
+
277
290
  ## Contributing
278
291
 
279
292
  1. Fork it ( https://github.com/styd/sd_struct/fork )
@@ -6,7 +6,7 @@ class SDStruct
6
6
  using Module.new {
7
7
  refine Hash do
8
8
  #
9
- # Change current Hash object to SDStruct object
9
+ # Changes current Hash object to SDStruct object
10
10
  #
11
11
  # @return [SDStruct] SDStruct object
12
12
  #
@@ -16,9 +16,8 @@ class SDStruct
16
16
  end
17
17
 
18
18
  refine Array do
19
-
20
19
  #
21
- # Call `to_struct` to an Array to go deeper or to a Hash to change it to SDStruct
20
+ # Calls `to_struct` to an Array to go deeper or to a Hash to change it to SDStruct
22
21
  #
23
22
  # @return [Array<SDStruct,Object>] array of SDStruct or any other objects
24
23
  #
@@ -42,18 +41,23 @@ class SDStruct
42
41
  #
43
42
  # p data # -> #<SDStruct .name="Matz", ['coding language']=:ruby, .age="old">
44
43
  #
45
- def initialize(hash = nil, deep = true)
46
- @deep = deep
44
+ def initialize(hash = nil, opts = {})
45
+ opts = {
46
+ deep: true,
47
+ symbolize_keys: true
48
+ }.merge(opts)
49
+
50
+ @deep = opts[:deep]
47
51
  @table = {}
48
52
  if hash
49
53
  hash.each_pair do |k, v|
50
- @table[new_struct_member(k)] = structurize(v) # @deep is used in this method
54
+ @table[naturalize(k)] = structurize(v) # @deep is used in this method
51
55
  end
52
56
  end
53
57
  end
54
58
 
55
59
  #
56
- # Duplicate an SDStruct object members.
60
+ # Duplicates an SDStruct object members.
57
61
  #
58
62
  def initialize_copy(orig)
59
63
  super
@@ -92,7 +96,6 @@ class SDStruct
92
96
  # Used internally to define field properties
93
97
  #
94
98
  def new_struct_member(name)
95
- name = name.to_s.underscore.to_sym unless name[/^[A-Z]|\s+/]
96
99
  unless respond_to?(name)
97
100
  define_singleton_method(name) { @table[name] }
98
101
  define_singleton_method("#{name}=") { |x| @table[name] = x }
@@ -100,14 +103,22 @@ class SDStruct
100
103
  name
101
104
  end
102
105
 
106
+ def naturalize(key)
107
+ unless key[/^[A-Z]|\s+/]
108
+ key.to_s.underscore.to_sym
109
+ else
110
+ key
111
+ end
112
+ end
113
+
103
114
  #
104
- # Call to struct to a value if it is an Array or a Hash and @deep is true
115
+ # Calls to struct to a value if it is an Array or a Hash and @deep is true
105
116
  #
106
117
  def structurize(value)
107
118
  ( @deep && (value.is_a?(Hash) || value.is_a?(Array)) ) ? value.to_struct : value
108
119
  end
109
120
 
110
- protected :new_struct_member, :structurize
121
+ protected :new_struct_member, :naturalize, :structurize
111
122
 
112
123
 
113
124
  #
@@ -117,7 +128,7 @@ class SDStruct
117
128
  # person[:lang] # => ruby, same as person.lang
118
129
  #
119
130
  def [](name)
120
- @table.has_key?(name) ? @table[name] : @table[name.to_s.underscore.to_sym]
131
+ @table[name] || @table[naturalize(name)]
121
132
  end
122
133
 
123
134
  #
@@ -128,21 +139,19 @@ class SDStruct
128
139
  # person.lang # => ruby
129
140
  #
130
141
  def []=(name, value)
131
- unless self.[](name).nil? || value.is_a?(self.[](name).class)
142
+ unless self[name].nil? || value.is_a?(self[name].class)
132
143
  warn("You're assigning a value with different type as the previous value.")
133
144
  end
134
- @table[new_struct_member(name)] = structurize(value)
145
+ @table[new_struct_member(naturalize(name))] = structurize(value)
135
146
  end
136
147
 
137
- InspectKey = :__inspect_key__ # :nodoc:
138
-
139
148
  #
140
149
  # Returns a string containing a detailed summary of the keys and values.
141
150
  #
142
151
  def inspect
143
152
  str = "#<#{self.class}"
144
153
 
145
- ids = (Thread.current[InspectKey] ||= [])
154
+ ids = (Thread.current[:sd_struct] ||= [])
146
155
  if ids.include?(object_id)
147
156
  return str << ' ...>'
148
157
  end
@@ -181,7 +190,7 @@ class SDStruct
181
190
  end
182
191
 
183
192
  #
184
- # Compute a hash-code for this SDStruct.
193
+ # Computes a hash-code for this SDStruct.
185
194
  # Two hashes with the same content will have the same hash code
186
195
  # (and will be eql?).
187
196
  #
@@ -190,14 +199,14 @@ class SDStruct
190
199
  end
191
200
 
192
201
  #
193
- # Expose keys with space(s)
202
+ # Exposes keys with space(s)
194
203
  #
195
204
  def spaced_keys
196
205
  @table.keys - non_spaced_keys
197
206
  end
198
207
 
199
208
  #
200
- # Expose keys without space(s)
209
+ # Exposes keys without space(s)
201
210
  #
202
211
  def non_spaced_keys
203
212
  methods(false).select{|x| x[/^\S+[^=]$/]}
@@ -205,21 +214,34 @@ class SDStruct
205
214
  alias :fields :non_spaced_keys
206
215
 
207
216
  #
208
- # Expose all keys
217
+ # Exposes all keys
209
218
  #
210
219
  def keys
211
220
  @table.keys
212
221
  end
213
222
 
214
223
  #
215
- # Delete specified field or key
224
+ # Deletes specified field or key
216
225
  #
217
226
  def delete_field(name)
218
- sym = name.to_sym
219
- @table.delete(sym) do
220
- raise NameError.new("no field `#{sym}' in #{self}", sym)
227
+ name = @table.has_key?(name) ? name : naturalize(name)
228
+ @table.delete(name) do
229
+ raise NameError.new("no field `#{name}' in #{self}", name)
221
230
  end
222
- singleton_class.__send__(:remove_method, sym, "#{sym}=")
231
+ singleton_class.__send__(:remove_method, name, "#{name}=")
223
232
  end
224
233
  alias :delete_key :delete_field
234
+
235
+ def method_missing(m_id, *args)
236
+ m_nat = naturalize(m_id)
237
+ if args.length.zero?
238
+ if @table.key?(m_nat)
239
+ @table[new_struct_member(m_nat)]
240
+ end
241
+ else
242
+ err = NoMethodError.new "undefined method `#{m_id}' for #{self}", m_id, args
243
+ err.set_backtrace caller(1)
244
+ raise err
245
+ end
246
+ end
225
247
  end
@@ -3,7 +3,7 @@ class SDStruct
3
3
  refine Array do
4
4
 
5
5
  #
6
- # Dig deep into array until non-Array and non-Hash primitive data is found
6
+ # Digs deep into array until non-Array and non-Hash primitive data is found
7
7
  #
8
8
  # @param [Symbol] multiple symbols
9
9
  # @return [String,Integer,Float,Boolean,nil] first matched result
@@ -32,7 +32,7 @@ class SDStruct
32
32
  }
33
33
 
34
34
  #
35
- # Dig deep into Hash until non-Array and non-Hash primitive data is found
35
+ # Digs deep into Hash until non-Array and non-Hash primitive data is found
36
36
  #
37
37
  # @param [Symbol] multiple symbols
38
38
  # @return [SDStruct,Hash,Array,String,Integer,Float,Boolean,nil] first matched result
@@ -60,7 +60,7 @@ class SDStruct
60
60
  end
61
61
 
62
62
  #
63
- # Dig the content of @table which is a hash
63
+ # Digs the content of @table which is a hash
64
64
  #
65
65
  # @param [Symbol] multiple symbols
66
66
  # @return [SDStruct,Hash,Array,String,Integer,Float,Boolean,nil] first matched result
@@ -69,6 +69,13 @@ class SDStruct
69
69
  @table.dig(*args)
70
70
  end
71
71
 
72
+ #
73
+ # Finds value with keys specified like xpath
74
+ #
75
+ # @param [String] key string
76
+ # @param [Hash] option Hash
77
+ # @return [SDStruct,Hash,Array,String,Integer,Float,Boolean,nil] first matched result
78
+ #
72
79
  def find(key_str, opts = {})
73
80
  opts = {
74
81
  separator: "/"
@@ -86,7 +93,7 @@ class SDStruct
86
93
  if !!x[/\A[-+]?\d+\z/]
87
94
  x.to_i
88
95
  else
89
- if x[/^$|\s+/]
96
+ if x[/^$|^[A-Z]|\s+/]
90
97
  x
91
98
  else
92
99
  x.underscore.to_sym
@@ -1,3 +1,3 @@
1
1
  class SDStruct
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -24,4 +24,5 @@ with deep digging capabilities.}
24
24
  spec.add_development_dependency "bundler", "~> 1.14"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "rspec", "~> 3.5"
27
+ spec.add_development_dependency "pry", "~> 0.10.4"
27
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sd_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Setyadi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-19 00:00:00.000000000 Z
11
+ date: 2017-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.10.4
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.10.4
69
83
  description: |-
70
84
  An alternative to OpenStruct that more strict in assigning values and deeper in
71
85
  consuming the passed Hash and transforming it back to Hash or JSON, equipped