dot_options 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb3d62c652e1453a6a6d4fcc5df1334c3998c257089fe8ac455bee3b93a7a3b2
4
- data.tar.gz: d52505910635b560f397d91d59a49001a625011eff3971e246791d46c62e65bd
3
+ metadata.gz: dcf63d2712a4a74313dbe914f5e52254243205f52c4715630a5dd84143dca366
4
+ data.tar.gz: 9be1281cc5d72168f23cb520d2d1e2a9a2c2a1427a3ff7298c48e8721de9a7a6
5
5
  SHA512:
6
- metadata.gz: 8c1e1384ad4a64014e35921c903a7994e38c97cab01441e3716ce659b5e1051390d9755065e6e6c4f8ec5af2507c34f32011569b5a080908ff219100c3c8f75d
7
- data.tar.gz: 2e6a4e3df06791a9eae4b10d2eac41b29bb814b0392f0ae600ee6d47fc8e99616aa975f37b8c1dd6e40b4df4ff53f0d3bb32ed46f735d70364df22b623c194ff
6
+ metadata.gz: fab0a8b1da7745406234335c7fe511df4f27e2149bfacc070fb72ed7116e3af794e1ab83659e5a7694a43c05599b0dde1f7fe4af038ff4b2d15d7052ce3f6d82
7
+ data.tar.gz: 17e1499a88d9a172fa07d265f765619840b22ff680bbfe0650777abfc3da049e9a0d1b767721fc18969d1b1ded40f7db949d418e175387173fa90fe450c6261f
data/README.md CHANGED
@@ -4,6 +4,7 @@ Convert any hash to a an object with deep read/write dot-notation access.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/dot_options.svg)](https://badge.fury.io/rb/dot_options)
6
6
  [![Build Status](https://github.com/DannyBen/dot_options/workflows/Test/badge.svg)](https://github.com/DannyBen/dot_options/actions?query=workflow%3ATest)
7
+ [![Maintainability](https://api.codeclimate.com/v1/badges/9506098f88fd04fdefae/maintainability)](https://codeclimate.com/github/DannyBen/dot_options/maintainability)
7
8
 
8
9
  ---
9
10
 
@@ -16,6 +17,9 @@ $ gem install dot_options
16
17
  ## Usage
17
18
 
18
19
  ```ruby
20
+ # Usage
21
+ require 'dot_options'
22
+
19
23
  # Initialize a DotOptions object with a hash:
20
24
  opts = {
21
25
  debug: true,
@@ -25,14 +29,78 @@ opts = {
25
29
  options = DotOptions.new opts
26
30
 
27
31
  # Read any option with dot-notation:
28
- p options.skin.background.color # => :black
32
+ p options.skin.background.color
33
+ #=> :black
29
34
 
30
- # Update any option with dot-notation:
35
+ # Update any option leaf with dot-notation:
31
36
  options.skin.background.color = :black
32
37
 
33
- # ... or create an entire branch by providing a hash
34
- options.skin.foreground = { color: :white, font: 'JetBrains Mono' }
35
- p options.skin.foreground.font # => 'JetBrains Mono'
38
+ # Print a flat view of all options
39
+ puts options
40
+ #=> debug = true
41
+ #=> output.color = true
42
+ #=> skin.background.color = :black
43
+ #=> skin.background.texture = "Stripes"
44
+
45
+ # ... or a compact inspection string for any branch
46
+ p options.skin
47
+ #=> <background: <color: :black, texture: "Stripes">>
48
+
49
+ # Access is also possible using []
50
+ p options.skin[:background].color
51
+ p options.skin[:background][:color]
52
+ #=> :black
53
+ #=> :black
54
+ ```
55
+
56
+ ### Subclassing
57
+
58
+ Subclassing `DotOptions` is a useful way to have an object with default options.
59
+
60
+ ```ruby
61
+ # Subclassing
62
+ require 'dot_options'
63
+
64
+ class Skin < DotOptions
65
+ def initialize(options = nil)
66
+ super defaults.merge(options || {})
67
+ end
68
+
69
+ def defaults
70
+ {
71
+ color: :black,
72
+ border: { color: :red, width: 3 },
73
+ background: { color: :lime, texture: 'Stripes' },
74
+ }
75
+ end
76
+ end
77
+
78
+ # Get an object with the default options
79
+ skin = Skin.new
80
+ p skin.background.color
81
+ #=> :lime
82
+
83
+ # Get an object and override some root options using a hash
84
+ skin = Skin.new color: :blue
85
+ p skin.color
86
+ #=> :blue
87
+
88
+ # Get an object and update some deep options using a block
89
+ skin = Skin.new { border.color = :yellow }
90
+ puts skin.border
91
+ #=> color = :yellow
92
+ #=> width = 3
93
+
94
+ # The initialization block receives the object itself which can be useful
95
+ # in some cases
96
+ skin = Skin.new do |skin|
97
+ skin.color = :cyan
98
+ skin.border.width = 10
99
+ end
100
+ p skin.color
101
+ p skin.border
102
+ #=> :cyan
103
+ #=> <color: :red, width: 10>
36
104
  ```
37
105
 
38
106
  ## Contributing / Support
@@ -1,3 +1,3 @@
1
1
  class DotOptions
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/dot_options.rb CHANGED
@@ -1,66 +1,71 @@
1
1
  class DotOptions
2
- OptionNotFoundError = Class.new StandardError
2
+ attr_reader :_options
3
+ attr_accessor :_key, :_parent, :_full_path
3
4
 
4
- attr_reader :options, :key, :parent
5
+ def initialize(base_options = nil, &block)
6
+ @_key = nil
7
+ @_parent = nil
8
+ @_options = []
9
+ @_full_path = []
10
+ _build_options(base_options || {})
11
+ instance_eval(&block) if block
12
+ end
5
13
 
6
- def initialize(options = {}, key: nil, parent: nil)
7
- @options = options
8
- @key = key
9
- @parent = parent
10
- build_options
14
+ def [](key)
15
+ _options.include?(key.to_sym) ? send(key.to_sym) : nil
11
16
  end
12
17
 
13
18
  def inspect
14
- "{ #{options.map { |key, value| "#{key}: #{value.inspect}" }.join(', ')} }"
19
+ "<#{_options.map { |key| "#{key}: #{send(key).inspect}" }.join(', ')}>"
15
20
  end
16
21
 
17
22
  def to_s
18
- flat_options.map { |key, value| "#{key} = #{value.inspect}" }.join "\n"
23
+ _flat_options.map { |key, value| "#{key} = #{value.inspect}" }.join "\n"
19
24
  end
20
25
 
21
- def flat_options(prefix = nil)
22
- result = {}
23
- options.each do |key, value|
24
- full_key = [prefix, key].compact.join '.'
25
- opts = value.is_a?(DotOptions) ? value.flat_options(full_key) : { full_key => value }
26
- result.merge! opts
26
+ def to_h
27
+ _options.to_h do |key|
28
+ value = send key
29
+ value = value.to_h if value.is_a? DotOptions
30
+ [key, value]
27
31
  end
28
-
29
- result
30
32
  end
31
33
 
32
- def method_missing(name, *args)
33
- if name.to_s.end_with?('=')
34
- key = name.to_s.chomp('=').to_sym
35
- options[key] = args.first
36
- build_options if args.first.is_a? Hash
37
- elsif options.has_key? name
38
- options[name]
39
- else
40
- raise OptionNotFoundError, "Option '#{full_path(name)}' not found"
41
- end
42
- end
34
+ protected
43
35
 
44
- def respond_to_missing?(name, include_private = false)
45
- options.has_key?(name.to_s.chomp('=').to_sym) || super
36
+ def _flat_options(prefix = nil)
37
+ result = {}
38
+ _options.each do |key|
39
+ value = send key
40
+ full_key = [prefix, key].compact.join('.')
41
+ opts = value.is_a?(DotOptions) ? value._flat_options(full_key) : { full_key => value }
42
+ result.merge! opts
43
+ end
44
+ result
46
45
  end
47
46
 
48
47
  private
49
48
 
50
- def build_options
49
+ def _build_options(options)
51
50
  options.each do |key, value|
52
- options[key] = DotOptions.new(value, key: key, parent: self) if value.is_a?(Hash)
51
+ _define_accessor key
52
+ if value.is_a? Hash
53
+ value = DotOptions.new value
54
+ value._full_path = _full_path + [key]
55
+ value._key = key
56
+ value._parent = self
57
+ end
58
+
59
+ send :"#{key}=", value
53
60
  end
54
61
  end
55
62
 
56
- def full_path(name)
57
- ancestors = [name]
58
- current = self
59
- while current.is_a? DotOptions
60
- ancestors.unshift(current.key) if current.key
61
- current = current.parent
62
- end
63
+ def _define_accessor(key)
64
+ raise NameError, "invalid attribute name `#{key}'" unless key.respond_to?(:to_sym)
63
65
 
64
- ancestors.join '.'
66
+ _options.push key.to_sym
67
+ singleton_class.class_eval do
68
+ attr_accessor key.to_sym
69
+ end
65
70
  end
66
71
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dot_options
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-30 00:00:00.000000000 Z
11
+ date: 2024-08-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Convert any hash to a deep dot-notation object
14
14
  email: db@dannyben.com
@@ -45,5 +45,5 @@ requirements: []
45
45
  rubygems_version: 3.5.14
46
46
  signing_key:
47
47
  specification_version: 4
48
- summary: Options object with dot-notation support
48
+ summary: Options object with dot-notation access
49
49
  test_files: []