dot_options 0.1.0 → 0.1.1

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: f2209fc78fa0d901b7662d743865fdaae4253e11542e940f42e3752f3ade4a31
4
+ data.tar.gz: cfddbb2c664850d59d272de160b341f9f2e840c03280d05e1ee290ed7109b079
5
5
  SHA512:
6
- metadata.gz: 8c1e1384ad4a64014e35921c903a7994e38c97cab01441e3716ce659b5e1051390d9755065e6e6c4f8ec5af2507c34f32011569b5a080908ff219100c3c8f75d
7
- data.tar.gz: 2e6a4e3df06791a9eae4b10d2eac41b29bb814b0392f0ae600ee6d47fc8e99616aa975f37b8c1dd6e40b4df4ff53f0d3bb32ed46f735d70364df22b623c194ff
6
+ metadata.gz: 0243d039b3d76e327abc4360df4e551ed14f09439bba4d2e4ad7134762bc8f504bc5e317953a3e9379d79a3e15d4bb713e16f1dd3708d816d888ef792b9628d5
7
+ data.tar.gz: 4dc4ac826ae86597529fb577650a03bb5c55ef099a4c925f39f767ca2dfaf8c7e559efc36dbc54b66705299b7a11b034c497f3f9185aa7ce5f1b2f99b3e057be
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,72 @@ 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
+
50
+ ### Subclassing
51
+
52
+ Subclassing `DotOptions` is a useful way to have an object with default options.
53
+
54
+ ```ruby
55
+ # Subclassing
56
+ require 'dot_options'
57
+
58
+ class Skin < DotOptions
59
+ def initialize(options = nil)
60
+ super defaults.merge(options || {})
61
+ end
62
+
63
+ def defaults
64
+ {
65
+ color: :black,
66
+ border: { color: :red, width: 3 },
67
+ background: { color: :lime, texture: 'Stripes' },
68
+ }
69
+ end
70
+ end
71
+
72
+ # Get an object with the default options
73
+ skin = Skin.new
74
+ p skin.background.color
75
+ #=> :lime
76
+
77
+ # Get an object and override some root options using a hash
78
+ skin = Skin.new color: :blue
79
+ p skin.color
80
+ #=> :blue
81
+
82
+ # Get an object and update some deep options using a block
83
+ skin = Skin.new { border.color = :yellow }
84
+ puts skin.border
85
+ #=> color = :yellow
86
+ #=> width = 3
87
+
88
+ # The initialization block receives the object itself which can be useful
89
+ # in some cases
90
+ skin = Skin.new do |skin|
91
+ skin.color = :cyan
92
+ skin.border.width = 10
93
+ end
94
+ p skin.color
95
+ p skin.border
96
+ #=> :cyan
97
+ #=> <color: :red, width: 10>
36
98
  ```
37
99
 
38
100
  ## Contributing / Support
@@ -1,3 +1,3 @@
1
1
  class DotOptions
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/lib/dot_options.rb CHANGED
@@ -1,66 +1,65 @@
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
-
6
- def initialize(options = {}, key: nil, parent: nil)
7
- @options = options
8
- @key = key
9
- @parent = parent
10
- build_options
5
+ def initialize(base_options = {}, &block)
6
+ @_key = nil
7
+ @_parent = nil
8
+ @_options = []
9
+ @_full_path = []
10
+ _build_options base_options
11
+ instance_eval(&block) if block
11
12
  end
12
13
 
13
14
  def inspect
14
- "{ #{options.map { |key, value| "#{key}: #{value.inspect}" }.join(', ')} }"
15
+ "<#{_options.map { |key| "#{key}: #{send(key).inspect}" }.join(', ')}>"
15
16
  end
16
17
 
17
18
  def to_s
18
- flat_options.map { |key, value| "#{key} = #{value.inspect}" }.join "\n"
19
+ _flat_options.map { |key, value| "#{key} = #{value.inspect}" }.join "\n"
19
20
  end
20
21
 
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
22
+ def to_h
23
+ _options.to_h do |key|
24
+ value = send key
25
+ value = value.to_h if value.is_a? DotOptions
26
+ [key, value]
27
27
  end
28
-
29
- result
30
28
  end
31
29
 
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
30
+ protected
43
31
 
44
- def respond_to_missing?(name, include_private = false)
45
- options.has_key?(name.to_s.chomp('=').to_sym) || super
32
+ def _flat_options(prefix = nil)
33
+ result = {}
34
+ _options.each do |key|
35
+ value = send key
36
+ full_key = [prefix, key].compact.join('.')
37
+ opts = value.is_a?(DotOptions) ? value._flat_options(full_key) : { full_key => value }
38
+ result.merge! opts
39
+ end
40
+ result
46
41
  end
47
42
 
48
43
  private
49
44
 
50
- def build_options
45
+ def _build_options(options)
51
46
  options.each do |key, value|
52
- options[key] = DotOptions.new(value, key: key, parent: self) if value.is_a?(Hash)
47
+ _define_accessor key
48
+ if value.is_a? Hash
49
+ value = DotOptions.new value
50
+ value._full_path = _full_path + [key]
51
+ value._key = key
52
+ value._parent = self
53
+ end
54
+
55
+ send :"#{key}=", value
53
56
  end
54
57
  end
55
58
 
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
59
+ def _define_accessor(key)
60
+ _options.push key
61
+ singleton_class.class_eval do
62
+ attr_accessor key.to_sym
62
63
  end
63
-
64
- ancestors.join '.'
65
64
  end
66
65
  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.1
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-02 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: []