key_tree 0.6.1 → 0.7.0
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/.gitignore +1 -0
- data/.rubocop.yml +0 -5
- data/{RELEASE_NOTES.md → CHANGELOG.md} +26 -0
- data/Gemfile +2 -8
- data/README.md +6 -1
- data/azure-pipelines.yml +22 -0
- data/bin/console +4 -4
- data/bin/setup +0 -1
- data/key_tree.gemspec +13 -6
- data/lib/key_tree.rb +65 -60
- data/lib/key_tree/forest.rb +2 -17
- data/lib/key_tree/loader.rb +17 -16
- data/lib/key_tree/path.rb +6 -6
- data/lib/key_tree/refine/deep_hash.rb +22 -11
- data/lib/key_tree/refinements.rb +4 -4
- data/lib/key_tree/tree.rb +4 -9
- data/ruby-keytree.sublime-project +8 -0
- metadata +52 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3dad4f9d7ee51efbc9cdf1b4c8e2f90dea321927ef73fb6081e8f437de43603
|
4
|
+
data.tar.gz: 7b52ebdbbdf1b4b5c172583aadb4d1f8006a56d1c970f530b28426d34af38ee9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa010f0942b8afddd4915cad9929b0aa166734c11cd5cd63e71e95b3f066266ac990ba1cfb8ad97f9133e14a94cba5bef7c39c84b30b3b1baebad0667b3aa5d7
|
7
|
+
data.tar.gz: f91c486c8f0c39dfadf767b3c44795974f521f324079de2a48478c9d3fb9611a4221f6481fe0a69e3354ac94d0f2114c84895966232674094d4e6498068cedba
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
Older releases uses an ad-hoc release notes format, and follow at the end.
|
8
|
+
|
9
|
+
|
10
|
+
## [Unreleased]
|
11
|
+
|
12
|
+
|
13
|
+
## [0.7.0] - 2019-07-16
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- Removed leftover private methods from `KeyTree::Forest`, `#tree_with_key`
|
18
|
+
and `#trees_with_key`
|
19
|
+
- Removed `KeyTree::Tree#fetch_default` method and simplified `#[]`
|
20
|
+
|
21
|
+
|
22
|
+
[Unreleased]: https://github.com/notCalle/PROJECT/compare/v0.7.0..HEAD
|
23
|
+
[0.7.0]: https://github.com/notCalle/PROJECT/compare/v0.6.1..v0.7.0
|
24
|
+
[0.6.1]: https://github.com/notCalle/PROJECT/releases/tag/v0.6.1
|
25
|
+
|
26
|
+
|
1
27
|
# Release Notes
|
2
28
|
|
3
29
|
## v0.6.1 – 2018-05-31
|
data/Gemfile
CHANGED
@@ -4,11 +4,5 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
rescue LoadError
|
10
|
-
gem 'git-version-bump', '~> 0.15'
|
11
|
-
else
|
12
|
-
# Specify your gem's dependencies in key_tree.gemspec
|
13
|
-
gemspec
|
14
|
-
end
|
7
|
+
# Specify your gem's dependencies in key_tree.gemspec
|
8
|
+
gemspec
|
data/README.md
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
[](https://badge.fury.io/rb/key_tree)
|
1
|
+
[](https://badge.fury.io/rb/key_tree)
|
2
|
+
[](https://codeclimate.com/github/notCalle/ruby-keytree/maintainability)
|
3
|
+
[](https://codecov.io/gh/notCalle/ruby-keytree)
|
4
|
+
[](https://dev.azure.com/notCalle/GitHub%20CI/_build/latest?definitionId=3&branchName=master)
|
2
5
|
|
3
6
|
# KeyTree
|
4
7
|
|
5
8
|
KeyTree manages trees of hashes, and (possibly nested) forests of such trees,
|
6
9
|
allowing access to values by key path.
|
7
10
|
|
11
|
+
See the [changelog](CHANGELOG.md) for recent changes.
|
12
|
+
|
8
13
|
## Installation
|
9
14
|
|
10
15
|
Add this line to your application's Gemfile:
|
data/azure-pipelines.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Ruby
|
2
|
+
# Package your Ruby project.
|
3
|
+
# Add steps that install rails, analyze code, save build artifacts, deploy, and more:
|
4
|
+
# https://docs.microsoft.com/azure/devops/pipelines/languages/ruby
|
5
|
+
|
6
|
+
pool:
|
7
|
+
vmImage: 'Ubuntu 16.04'
|
8
|
+
|
9
|
+
steps:
|
10
|
+
- task: UseRubyVersion@0
|
11
|
+
inputs:
|
12
|
+
versionSpec: '>= 2.5'
|
13
|
+
|
14
|
+
- script: |
|
15
|
+
gem install bundler
|
16
|
+
bin/setup
|
17
|
+
displayName: 'bundle install'
|
18
|
+
|
19
|
+
- script: bundle exec rake
|
20
|
+
displayName: 'bundle exec rake'
|
21
|
+
env:
|
22
|
+
CODECOV_TOKEN: $(codecov.token)
|
data/bin/console
CHANGED
@@ -8,8 +8,8 @@ require 'key_tree'
|
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
9
9
|
|
10
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
-
|
12
|
-
|
11
|
+
require 'pry'
|
12
|
+
Pry.start
|
13
13
|
|
14
|
-
require 'irb'
|
15
|
-
IRB.start(__FILE__)
|
14
|
+
# require 'irb'
|
15
|
+
# IRB.start(__FILE__)
|
data/bin/setup
CHANGED
data/key_tree.gemspec
CHANGED
@@ -5,6 +5,18 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
require 'key_tree/version'
|
7
7
|
|
8
|
+
dev_deps = {
|
9
|
+
'bundler' => '~> 2.0',
|
10
|
+
'codecov' => '~> 0.1',
|
11
|
+
'git-version-bump' => '~> 0.15',
|
12
|
+
'pry' => '~> 0.11',
|
13
|
+
'rake' => '~> 10.0',
|
14
|
+
'rspec' => '~> 3.0',
|
15
|
+
'rubocop' => '~> 0.57',
|
16
|
+
'ruby-prof' => '~> 0.17',
|
17
|
+
'simplecov' => '~> 0.16'
|
18
|
+
}
|
19
|
+
|
8
20
|
Gem::Specification.new do |spec|
|
9
21
|
spec.name = 'key_tree'
|
10
22
|
spec.version = KeyTree::VERSION
|
@@ -25,10 +37,5 @@ Gem::Specification.new do |spec|
|
|
25
37
|
spec.platform = Gem::Platform::RUBY
|
26
38
|
spec.required_ruby_version = '~> 2.3'
|
27
39
|
|
28
|
-
|
29
|
-
spec.add_development_dependency 'git-version-bump', '~> 0.15'
|
30
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
31
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
-
spec.add_development_dependency 'rubocop', '~> 0.52'
|
33
|
-
spec.add_development_dependency 'ruby-prof', '~> 0.17'
|
40
|
+
dev_deps.each { |d| spec.add_development_dependency(*d) }
|
34
41
|
end
|
data/lib/key_tree.rb
CHANGED
@@ -17,77 +17,82 @@ require 'key_tree/tree'
|
|
17
17
|
module KeyTree
|
18
18
|
using Refinements
|
19
19
|
|
20
|
-
|
21
|
-
contents
|
22
|
-
|
20
|
+
class << self
|
21
|
+
def [](contents = {})
|
22
|
+
contents.to_key_wood
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
25
|
+
# Load a KeyTree from some external serialization
|
26
|
+
#
|
27
|
+
# load +type+: +serialization+
|
28
|
+
# load +key_prefix+, +type+: +serialization+
|
29
|
+
#
|
30
|
+
# +type+ is upcased to form a class name that should provide a
|
31
|
+
# +.load+ class method (like YAML or JSON does).
|
32
|
+
#
|
33
|
+
# If a +key_prefix+ is given, it will be prepended to the loaded data.
|
34
|
+
#
|
35
|
+
# Examples:
|
36
|
+
# load(:yaml, "---\na: 1\n")
|
37
|
+
# => {"a" => 1}
|
38
|
+
#
|
39
|
+
# load(:yaml, "---\nb: 2\n", prefix: 'a')
|
40
|
+
# => {"a.b" => 2}
|
41
|
+
#
|
42
|
+
def load(type, serialization, prefix: nil)
|
43
|
+
type = type.to_sym unless type.nil?
|
44
|
+
loader = Loader[type]
|
45
|
+
contents = loader.load(serialization)
|
46
|
+
contents = { prefix => contents } unless prefix.nil?
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
contents.to_key_wood.with_meta_data do |meta_data|
|
49
|
+
meta_data << { load: { type: type, loader: loader } }
|
50
|
+
meta_data << { load: { prefix: prefix } } unless prefix.nil?
|
51
|
+
end
|
50
52
|
end
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
# Open an external file and load contents into a KeyTree
|
55
|
+
# When the file basename begins with 'prefix@', the prefix
|
56
|
+
# is prepended to all keys in the filee.
|
57
|
+
def open(file_name)
|
58
|
+
type = File.extname(file_name)[/[^.]+/]
|
59
|
+
prefix = File.basename(file_name)[/(.+)@/, 1]
|
60
|
+
|
61
|
+
keytree = File.open(file_name, mode: 'rb:utf-8') do |file|
|
62
|
+
load_from_file(file, type, prefix)
|
63
|
+
end
|
59
64
|
|
60
|
-
|
61
|
-
|
65
|
+
return keytree unless block_given?
|
66
|
+
|
67
|
+
yield keytree
|
62
68
|
end
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
# Open all files in a directory and load their contents into
|
71
|
+
# a Forest of Trees, optionally following symlinks, and recursing.
|
72
|
+
def open_all(dir_name, follow_links: false, recurse: false)
|
73
|
+
Dir.children(dir_name).reduce(KeyTree::Forest.new) do |result, file|
|
74
|
+
path = File.join(dir_name, file)
|
75
|
+
next result if File.symlink?(path) && !follow_links
|
67
76
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
next result << open(path) if stat.file?
|
77
|
-
# rubocop:enable Security/Open
|
78
|
-
next result unless recurse && stat.directory?
|
79
|
-
result << open_all(path, follow_links: follow_links, recurse: true)
|
77
|
+
stat = File.stat(path)
|
78
|
+
# rubocop:disable Security/Open
|
79
|
+
next result << open(path) if stat.file?
|
80
|
+
# rubocop:enable Security/Open
|
81
|
+
next result unless recurse && stat.directory?
|
82
|
+
|
83
|
+
result << open_all(path, follow_links: follow_links, recurse: true)
|
84
|
+
end
|
80
85
|
end
|
81
|
-
end
|
82
86
|
|
83
|
-
|
87
|
+
private
|
84
88
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
89
|
+
def load_from_file(file, type, prefix)
|
90
|
+
load(type, file.read, prefix: prefix).with_meta_data do |meta_data|
|
91
|
+
file_path = file.path
|
92
|
+
meta_data << { file: { path: file_path,
|
93
|
+
name: File.basename(file_path),
|
94
|
+
dir: File.dirname(file_path) } }
|
95
|
+
end
|
91
96
|
end
|
92
97
|
end
|
93
98
|
end
|
data/lib/key_tree/forest.rb
CHANGED
@@ -57,6 +57,7 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
57
57
|
end
|
58
58
|
return yield(key) if block_given?
|
59
59
|
return default.first unless default.empty?
|
60
|
+
|
60
61
|
raise KeyError, %(key not found: "#{key}")
|
61
62
|
end
|
62
63
|
|
@@ -99,6 +100,7 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
99
100
|
remaining = [self]
|
100
101
|
remaining.each do |woods|
|
101
102
|
next yielder << woods if woods.is_a?(Tree)
|
103
|
+
|
102
104
|
woods.each { |wood| remaining << wood }
|
103
105
|
end
|
104
106
|
end
|
@@ -108,22 +110,5 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
108
110
|
def key_paths
|
109
111
|
trees.reduce(Set.new) { |result, tree| result.merge(tree.key_paths) }
|
110
112
|
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
def tree_with_key(key)
|
115
|
-
result = trees.lazy.detect do |tree|
|
116
|
-
tree.prefix?(key)
|
117
|
-
end
|
118
|
-
result || raise(KeyError, %(key not found: "#{key}"))
|
119
|
-
end
|
120
|
-
|
121
|
-
def trees_with_key(key)
|
122
|
-
result = trees.select do |tree|
|
123
|
-
tree.prefix?(key)
|
124
|
-
end
|
125
|
-
raise(KeyError, %(key not found: "#{key}")) if result.empty?
|
126
|
-
result
|
127
|
-
end
|
128
113
|
end
|
129
114
|
end
|
data/lib/key_tree/loader.rb
CHANGED
@@ -10,26 +10,27 @@ module KeyTree
|
|
10
10
|
yaml: 'YAML', yml: 'YAML'
|
11
11
|
}.freeze
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
class << self
|
14
|
+
def [](type)
|
15
|
+
type = type.to_sym if type.respond_to?(:to_sym)
|
16
|
+
loaders[type] || @fallback
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def []=(type, loader_class)
|
20
|
+
type = type.to_sym if type.respond_to?(:to_sym)
|
21
|
+
loaders[type] = loader_class
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
24
|
+
attr_writer :fallback, :loaders
|
25
|
+
alias fallback fallback=
|
26
26
|
|
27
|
-
|
27
|
+
private
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
def loaders
|
30
|
+
@loaders ||= BUILTIN_LOADERS.each_with_object({}) do |pair, result|
|
31
|
+
type, name = pair
|
32
|
+
result[type] = const_get(name) if const_defined?(name)
|
33
|
+
end
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
data/lib/key_tree/path.rb
CHANGED
@@ -16,7 +16,7 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
16
16
|
#
|
17
17
|
def self.[](*key_paths)
|
18
18
|
key_paths.reduce(Path.new) do |result, key_path|
|
19
|
-
result << key_path
|
19
|
+
result << Path.new(key_path)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -41,9 +41,7 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
|
-
self
|
46
|
-
end
|
44
|
+
alias to_key_path itself
|
47
45
|
|
48
46
|
def to_s
|
49
47
|
join('.')
|
@@ -64,10 +62,11 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
64
62
|
# Returns a key path without the leading +prefix+
|
65
63
|
#
|
66
64
|
# :call-seq:
|
67
|
-
#
|
68
|
-
def
|
65
|
+
# drop(other) => Path
|
66
|
+
def drop(other)
|
69
67
|
other = other.to_key_path
|
70
68
|
raise KeyError unless prefix?(other)
|
69
|
+
|
71
70
|
super(other.length)
|
72
71
|
end
|
73
72
|
|
@@ -78,6 +77,7 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
78
77
|
def prefix?(other)
|
79
78
|
other = other.to_key_path
|
80
79
|
return false if other.length > length
|
80
|
+
|
81
81
|
key_enum = each
|
82
82
|
other.all? { |other_key| key_enum.next == other_key }
|
83
83
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../path'
|
4
|
-
|
5
3
|
module KeyTree
|
6
4
|
module Refine
|
7
5
|
# Refinements to Hash for deep_ methods, for traversing nested structures
|
8
6
|
module DeepHash
|
9
|
-
refine Hash do
|
7
|
+
refine Hash do
|
10
8
|
# Return a deep enumerator for all (+key_path+, +value+) pairs in a
|
11
9
|
# nested hash structure.
|
12
10
|
#
|
@@ -34,6 +32,7 @@ module KeyTree
|
|
34
32
|
end
|
35
33
|
return yield(key_path) if block_given?
|
36
34
|
return default.first unless default.empty?
|
35
|
+
|
37
36
|
raise KeyError, %(key path invalid: "#{key_path}")
|
38
37
|
end
|
39
38
|
|
@@ -49,6 +48,7 @@ module KeyTree
|
|
49
48
|
result = prefix_path.reduce(self) do |hash, key|
|
50
49
|
result = hash.fetch(key) { hash[key] = {} }
|
51
50
|
next result if result.is_a?(Hash)
|
51
|
+
|
52
52
|
raise KeyError, %(prefix has value: "#{key_path}")
|
53
53
|
end
|
54
54
|
result[last_key] = new_value
|
@@ -65,6 +65,7 @@ module KeyTree
|
|
65
65
|
result = prefix_path.reduce(self) do |hash, key|
|
66
66
|
result = hash.fetch(key, nil)
|
67
67
|
next result if result.is_a?(Hash)
|
68
|
+
|
68
69
|
raise KeyError, %(prefix has value: "#{key_path}")
|
69
70
|
end
|
70
71
|
result.delete(last_key)
|
@@ -74,11 +75,14 @@ module KeyTree
|
|
74
75
|
#
|
75
76
|
# :call-seq:
|
76
77
|
# deep_merge!(other) => self
|
77
|
-
# deep_merge!(other) { |
|
78
|
-
def deep_merge!(other)
|
78
|
+
# deep_merge!(other) { |key_path, lhs, rhs| } => self
|
79
|
+
def deep_merge!(other, prefix = [], &block)
|
79
80
|
merge!(other) do |key, lhs, rhs|
|
80
|
-
|
81
|
-
|
81
|
+
key_path = prefix + [key]
|
82
|
+
both_are_hashes = lhs.is_a?(Hash) && rhs.is_a?(Hash)
|
83
|
+
next lhs.deep_merge!(rhs, key_path, &block) if both_are_hashes
|
84
|
+
next yield(key_path, lhs, rhs) unless block.nil?
|
85
|
+
|
82
86
|
rhs
|
83
87
|
end
|
84
88
|
end
|
@@ -87,11 +91,14 @@ module KeyTree
|
|
87
91
|
#
|
88
92
|
# :call-seq:
|
89
93
|
# deep_merge(other) => self
|
90
|
-
# deep_merge(other) { |
|
91
|
-
def deep_merge(other)
|
94
|
+
# deep_merge(other) { |key_path, lhs, rhs| } => self
|
95
|
+
def deep_merge(other, prefix = [], &block)
|
92
96
|
merge(other) do |key, lhs, rhs|
|
93
|
-
|
94
|
-
|
97
|
+
key_path = prefix + [key]
|
98
|
+
both_are_hashes = lhs.is_a?(Hash) && rhs.is_a?(Hash)
|
99
|
+
next lhs.deep_merge(rhs, key_path, &block) if both_are_hashes
|
100
|
+
next yield(key_path, lhs, rhs) unless block.nil?
|
101
|
+
|
95
102
|
rhs
|
96
103
|
end
|
97
104
|
end
|
@@ -104,6 +111,7 @@ module KeyTree
|
|
104
111
|
result = transform_keys(&block)
|
105
112
|
result.transform_values! do |value|
|
106
113
|
next value unless value.is_a?(Hash)
|
114
|
+
|
107
115
|
value.deep_transform_keys(&block)
|
108
116
|
end
|
109
117
|
end
|
@@ -116,6 +124,7 @@ module KeyTree
|
|
116
124
|
result = transform_keys!(&block)
|
117
125
|
result.transform_values! do |value|
|
118
126
|
next value unless value.is_a?(Hash)
|
127
|
+
|
119
128
|
value.deep_transform_keys!(&block)
|
120
129
|
end
|
121
130
|
end
|
@@ -144,3 +153,5 @@ module KeyTree
|
|
144
153
|
end
|
145
154
|
end
|
146
155
|
end
|
156
|
+
|
157
|
+
require_relative '../path'
|
data/lib/key_tree/refinements.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'forest'
|
4
|
-
require_relative 'path'
|
5
|
-
require_relative 'tree'
|
6
|
-
|
7
3
|
module KeyTree
|
8
4
|
# KeyTree refinements to core classes
|
9
5
|
module Refinements
|
@@ -38,3 +34,7 @@ module KeyTree
|
|
38
34
|
end
|
39
35
|
end
|
40
36
|
end
|
37
|
+
|
38
|
+
require_relative 'forest'
|
39
|
+
require_relative 'path'
|
40
|
+
require_relative 'tree'
|
data/lib/key_tree/tree.rb
CHANGED
@@ -45,17 +45,11 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def [](key_path)
|
48
|
-
|
49
|
-
|
48
|
+
fetch(key_path) do
|
49
|
+
next default if default_proc.nil?
|
50
50
|
|
51
|
-
|
52
|
-
catch do |ball|
|
53
|
-
return fetch(key_path) { throw ball }
|
51
|
+
default_proc.call(self, key_path)
|
54
52
|
end
|
55
|
-
return default_proc.call(self, key_path) unless default_proc.nil?
|
56
|
-
return yield(key_path) if block_given?
|
57
|
-
return default.first unless default.empty?
|
58
|
-
raise KeyError, %(key not found: "#{key_path}")
|
59
53
|
end
|
60
54
|
|
61
55
|
def fetch(key_path, *args, &key_missing)
|
@@ -115,6 +109,7 @@ module KeyTree # rubocop:disable Style/Documentation
|
|
115
109
|
key_path.to_key_path.reduce(@hash) do |subtree, key|
|
116
110
|
return false unless subtree.is_a?(Hash)
|
117
111
|
return false unless subtree.key?(key)
|
112
|
+
|
118
113
|
subtree[key]
|
119
114
|
end
|
120
115
|
true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: key_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Calle Englund
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: codecov
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: git-version-bump
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +52,20 @@ dependencies:
|
|
38
52
|
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0.15'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rake
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +100,14 @@ dependencies:
|
|
72
100
|
requirements:
|
73
101
|
- - "~>"
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0.
|
103
|
+
version: '0.57'
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0.
|
110
|
+
version: '0.57'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: ruby-prof
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +122,20 @@ dependencies:
|
|
94
122
|
- - "~>"
|
95
123
|
- !ruby/object:Gem::Version
|
96
124
|
version: '0.17'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.16'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.16'
|
97
139
|
description:
|
98
140
|
email:
|
99
141
|
- calle@discord.bofh.se
|
@@ -105,12 +147,13 @@ files:
|
|
105
147
|
- ".rspec"
|
106
148
|
- ".rubocop.yml"
|
107
149
|
- ".travis.yml"
|
150
|
+
- CHANGELOG.md
|
108
151
|
- CODE_OF_CONDUCT.md
|
109
152
|
- Gemfile
|
110
153
|
- LICENSE.txt
|
111
154
|
- README.md
|
112
|
-
- RELEASE_NOTES.md
|
113
155
|
- Rakefile
|
156
|
+
- azure-pipelines.yml
|
114
157
|
- bin/console
|
115
158
|
- bin/setup
|
116
159
|
- key_tree.gemspec
|
@@ -124,6 +167,7 @@ files:
|
|
124
167
|
- lib/key_tree/refinements.rb
|
125
168
|
- lib/key_tree/tree.rb
|
126
169
|
- lib/key_tree/version.rb
|
170
|
+
- ruby-keytree.sublime-project
|
127
171
|
homepage: https://github.com/notcalle/ruby-keytree
|
128
172
|
licenses:
|
129
173
|
- MIT
|
@@ -143,8 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
187
|
- !ruby/object:Gem::Version
|
144
188
|
version: '0'
|
145
189
|
requirements: []
|
146
|
-
|
147
|
-
rubygems_version: 2.7.6
|
190
|
+
rubygems_version: 3.0.3
|
148
191
|
signing_key:
|
149
192
|
specification_version: 4
|
150
193
|
summary: Manage trees of keys
|