hash_dial 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9a2e69ddcb5f84bef6fa164953fa3a127396568cd91ee1debbad926902e29df3
4
+ data.tar.gz: efa91b61097992c4b3a57545d9cb64af8cd4a9fa924277e2c5f1af60f967e1bb
5
+ SHA512:
6
+ metadata.gz: b776b72153e96ff264e3c859cb1a12b37a06d8baa3538735e34dcffb8331780597ed119cc032c11ccdb70379f45f888ec497b09c417aeab794cc5917c29660ae
7
+ data.tar.gz: 4c38e006c1140bb59afc72e2fadb347e40887c49e5b7274d59e2b9cef1c33e54fde80ff475944ed9bb541ddc296ccad9a0ff61a6d86b413993e1ef03dded41a9
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ .git
2
+ .env
3
+ *.lnk
4
+ *.db
5
+ *.ini
6
+
7
+ /.bundle/
8
+ /.yardoc
9
+ /_yardoc/
10
+ /coverage/
11
+ /doc/
12
+ /pkg/
13
+ /spec/reports/
14
+ /tmp/
15
+
16
+ # rspec failure tracking
17
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.4.3
7
+ before_install: gem install bundler -v 1.17.2
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in hash_dial.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hash_dial (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (10.5.0)
11
+ rspec (3.8.0)
12
+ rspec-core (~> 3.8.0)
13
+ rspec-expectations (~> 3.8.0)
14
+ rspec-mocks (~> 3.8.0)
15
+ rspec-core (3.8.0)
16
+ rspec-support (~> 3.8.0)
17
+ rspec-expectations (3.8.2)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.8.0)
20
+ rspec-mocks (3.8.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-support (3.8.0)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.17)
30
+ hash_dial!
31
+ rake (~> 10.0)
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 1.17.2
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # HashDial
2
+
3
+ **Avoid all errors when accessing a deeply nested Hash key.** HashDial goes one step beyond Hash::dig() by returning nil (or your default) if the keys requested are invalid for any reason.
4
+
5
+ In particular, if you try to access a key on a value that isn't a hash, dig() will cause an error where HashDial will not.
6
+
7
+ ```ruby
8
+ hash = {a: {b: {c: true}, d: 5}}
9
+ hash.dig( :a, :d, :c) #=> TypeError: Integer does not have #dig method
10
+ hash.call(:a, :d, :c) #=> nil
11
+ hash.call(:a, :b, :c) #=> true
12
+ ```
13
+
14
+ **Bonus: you don't even need to fiddle with existing code.** If you have already written something to access a deep hash key, just surround this with `dial` and `call` (rather than changing it to the form above as function parameters).
15
+
16
+ ```ruby
17
+ hash[:a][:d][:c] #=> TypeError: no implicit conversion of Symbol into Integer
18
+ #hash → [:a][:d][:c]
19
+ # ↓ ↓
20
+ hash.dial[:a][:d][:c].call #=> nil
21
+ ```
22
+
23
+ ## Explanation
24
+
25
+ We use the concept of placing a phone-call: you can 'dial' any set of keys regardless of whether they exist (like entering a phone number), then finally place the 'call'. If the key is invalid for any reason you get nil/default (like a wrong number); otherwise you get the value (you're connected).
26
+
27
+ This works by intermediating your request with a HashDialler object. Trying to access keys on this object simply builds up a list of keys to use when you later place the 'call'.
28
+
29
+ ## Installation
30
+
31
+ Add this line to your application's Gemfile:
32
+
33
+ ```ruby
34
+ gem 'hash_dial'
35
+ ```
36
+
37
+ And then execute:
38
+
39
+ $ bundle
40
+
41
+ Or install it yourself as:
42
+
43
+ $ gem install hash_dial
44
+
45
+ ## Usage
46
+
47
+ ```ruby
48
+ require 'hash_dial'
49
+ ```
50
+
51
+ ### Use it like dig()
52
+
53
+ If you want to follow this pattern, it works in the same way. You can't change the default return value when using this pattern.
54
+
55
+ ```ruby
56
+ hash.call(:a, :b, :c) #=> Returns the value at hash[:a][:b][:c] or nil
57
+ ```
58
+
59
+ ### Use it like a Hash -- allows default return value
60
+
61
+ ```ruby
62
+ hash.dial[:a][:b][:c].call #=> Returns the value at hash[:a][:b][:c] or nil
63
+ hash.dial[:a][:b][:c].call('Ooops') #=> Returns the value at hash[:a][:b][:c] or 'Ooops'
64
+ ```
65
+
66
+ If you don't do this all in one line, you can access the HashDialler object should you want to manipulate it:
67
+
68
+ ```ruby
69
+ dialler = hash.dial # Returns a HashDialler object referencing hash
70
+ dialler[:a] # Adds :a to the list of keys to dial (returns self)
71
+ dialler.dial!(:b, :c) # Longhand way of adding more keys (returns self)
72
+ dialler.undial! # Removes the last-added key (returns self)
73
+ dialler[:c][:d] # Adds two more keys (returns self)
74
+ dialler += :e # Adds yet one more (returns self)
75
+ dialler -= :a # Removes all such keys from the list (returns self)
76
+ # So far we have dialled [:b][:c][:d][:e]
77
+ dialler.call #=> Returns the value at hash[:b][:c][:d][:e] or nil
78
+ dialler.hangup #=> Returns the original hash by reference
79
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "hash_dial"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/hash_dial.gemspec ADDED
@@ -0,0 +1,28 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "hash_dial/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hash_dial"
8
+ spec.version = HashDial::VERSION
9
+ spec.authors = ["Convincible"]
10
+ spec.email = ["development@convincible.media"]
11
+
12
+ spec.summary = "Access (deeply nested) hash keys. Get the value, or nil on any error. (Even safer than Hash::dig)."
13
+ spec.description = "Avoid all errors when accessing a (deeply nested) Hash key. HashDial goes one step beyond Hash::dig() by returning nil (or your default) if the keys requested are invalid for any reason at all. Bonus: you don't even need to fiddle with existing code. If you have already written something to access a deep hash key, just surround this with '.dial' and '.call'."
14
+ spec.homepage = "https://github.com/ConvincibleMedia/hash_dial"
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.17"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ end
data/lib/hash_dial.rb ADDED
@@ -0,0 +1,20 @@
1
+ require "hash_dial/version"
2
+ require "hash_dial/hash_dialler"
3
+
4
+ module HashDial
5
+
6
+ def to_dial(*lookup)
7
+ return HashDialler.new(self, *lookup)
8
+ end
9
+
10
+ alias_method :dial, :to_dial
11
+
12
+ def call(*lookup)
13
+ return HashDialler.new(self, *lookup).call
14
+ end
15
+
16
+ end
17
+
18
+ class Hash
19
+ include HashDial
20
+ end
@@ -0,0 +1,61 @@
1
+ module HashDial
2
+
3
+ class HashDialler
4
+
5
+ @hash
6
+ @lookup
7
+ @default = nil
8
+
9
+ def initialize(hash, *lookup)
10
+ if hash.is_a?(Hash)
11
+ @hash = hash
12
+ else
13
+ @hash = {}
14
+ end
15
+ @lookup = []
16
+ if lookup.length > 0
17
+ dial!(*lookup)
18
+ end
19
+ end
20
+
21
+ def dial!(*keys)
22
+ #unless key.is_a(Symbol) || key.is_a(String)
23
+ @lookup += keys
24
+ return self
25
+ end
26
+
27
+ def call(default = nil)
28
+ begin
29
+ value = @hash.dig(*@lookup)
30
+ rescue
31
+ value = default
32
+ end
33
+ return value
34
+ end
35
+
36
+ def hangup
37
+ return @hash
38
+ end
39
+
40
+ def undial!(*keys)
41
+ if keys.length > 0
42
+ @lookup -= keys
43
+ elsif @lookup.length > 0
44
+ @lookup.pop
45
+ end
46
+ return self
47
+ end
48
+
49
+ def [](key)
50
+ return dial!(key)
51
+ end
52
+ def +(key)
53
+ return dial!(key)
54
+ end
55
+ def -(key)
56
+ return undial!(key)
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,3 @@
1
+ module HashDial
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hash_dial
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Convincible
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: 'Avoid all errors when accessing a (deeply nested) Hash key. HashDial
56
+ goes one step beyond Hash::dig() by returning nil (or your default) if the keys
57
+ requested are invalid for any reason at all. Bonus: you don''t even need to fiddle
58
+ with existing code. If you have already written something to access a deep hash
59
+ key, just surround this with ''.dial'' and ''.call''.'
60
+ email:
61
+ - development@convincible.media
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - ".gitignore"
67
+ - ".rspec"
68
+ - ".travis.yml"
69
+ - Gemfile
70
+ - Gemfile.lock
71
+ - README.md
72
+ - Rakefile
73
+ - bin/console
74
+ - bin/setup
75
+ - hash_dial.gemspec
76
+ - lib/hash_dial.rb
77
+ - lib/hash_dial/hash_dialler.rb
78
+ - lib/hash_dial/version.rb
79
+ homepage: https://github.com/ConvincibleMedia/hash_dial
80
+ licenses: []
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubygems_version: 3.0.0
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Access (deeply nested) hash keys. Get the value, or nil on any error. (Even
101
+ safer than Hash::dig).
102
+ test_files: []