hash-to-obj 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +28 -0
- data/Rakefile +10 -0
- data/bin/setup +8 -0
- data/hash-to-obj.gemspec +28 -0
- data/lib/hash-to-obj.rb +115 -0
- data/lib/hash-to-obj/version.rb +3 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ee934fea5eddeefa8540e7691d2b39b28e1e948c
|
4
|
+
data.tar.gz: b5b7c45e8ffd2d74b4cd84f4051a2184a85c4d2f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b79470f4236a73cab06c10bb5494fdcd20e62ee98c9802854b4325497203e4193dbca745ff1c66857b8da66cf0eed2fecd62b25975d15780e5de3c1fdd6e7321
|
7
|
+
data.tar.gz: e19f7befcd4897b53aa8cbb170928222317570532bdbe6c5180e651dc718443709cb82b95cb88c71367898ca8eae5bfc110d8e4932641d78c9132735b2835e02
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
## Installation
|
2
|
+
|
3
|
+
Add this line to your application's Gemfile:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
gem 'hash-to-obj'
|
7
|
+
```
|
8
|
+
|
9
|
+
And then execute:
|
10
|
+
|
11
|
+
$ bundle
|
12
|
+
|
13
|
+
Or install it yourself as:
|
14
|
+
|
15
|
+
$ gem install hash-to-obj
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
Once installed you can simply call `objectify` on a hash to objectify it!
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
my_hash = { a: 1, b: 2, c: 3 }
|
23
|
+
objectify my_hash
|
24
|
+
my_hash.a # 1
|
25
|
+
my_hash.b = "b" # { a: 1, b: "b", c: 3 }
|
26
|
+
```
|
27
|
+
|
28
|
+
If you add new elements to the hash it will not currently create helper methods.
|
data/Rakefile
ADDED
data/bin/setup
ADDED
data/hash-to-obj.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hash-to-obj/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'hash-to-obj'
|
8
|
+
spec.version = HashToObj::VERSION
|
9
|
+
spec.authors = ['Sam Maxwell']
|
10
|
+
spec.email = ['raindropenter@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Simple Ruby gem to objectify hashes'
|
13
|
+
spec.description = "Call 'objectify my_hash' to add accessor methods to "\
|
14
|
+
'my_hash based on the keys currently in the has.'
|
15
|
+
spec.homepage = 'https://github.com/ReinAkane/hash-to-obj'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'pry', '>= 0'
|
28
|
+
end
|
data/lib/hash-to-obj.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'hash-to-obj/version'
|
2
|
+
|
3
|
+
##
|
4
|
+
# We extend this to objectify our hashes. It will generate some methods on the
|
5
|
+
# hash to access the various keys.
|
6
|
+
#
|
7
|
+
# Define a constant HashToObj::SQUELCH_GLOBAL_WARNINGS to squelch warnings about
|
8
|
+
# objectify already being defined.
|
9
|
+
module HashToObj
|
10
|
+
##
|
11
|
+
# Anything that you want to objectify needs to respond to these methods like a
|
12
|
+
# Hash would. If it doesn't at least respond_to? these methods, an error will
|
13
|
+
# be thrown when objectifying.
|
14
|
+
DUCK_TYPE_API = [:[], :[]=].freeze
|
15
|
+
|
16
|
+
##
|
17
|
+
# Throws an error if hash doesn't have all messages defined in DUCK_TYPE_API.
|
18
|
+
# Generates the accessors for all keys on the passed hash. Unless
|
19
|
+
# override_warnings is true-y, this will throw errors if we're gonna screw
|
20
|
+
# anything up. If you pass something that responds to :puts in
|
21
|
+
# override_warnings then warnings will just be puts'd to that, and things will
|
22
|
+
# continue.
|
23
|
+
def self.objectify(hash, override_warnings = false)
|
24
|
+
# Make sure it looks SOMEWHAT familiar.
|
25
|
+
DUCK_TYPE_API.each do |method_sym|
|
26
|
+
unless hash.respond_to?(method_sym) then
|
27
|
+
raise(ArgumentError,
|
28
|
+
"Cannot objectify something that doesn't look like a hash.")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Now lets actually add those methods.
|
33
|
+
hash.each_key do |key|
|
34
|
+
generate_accessors(hash, key, override_warnings)
|
35
|
+
end
|
36
|
+
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Generates the accessors for the passed key on the passed hash. Unless
|
42
|
+
# override_warnings is true-y, this will throw errors if we're gonna screw
|
43
|
+
# anything up. If you pass something that responds to :puts in
|
44
|
+
# override_warnings then warnings will just be puts'd to that, and things will
|
45
|
+
# continue.
|
46
|
+
def self.generate_accessors(hash, key, override_warnings = false)
|
47
|
+
handle_warnings(hash, key, override_warnings)
|
48
|
+
|
49
|
+
valid_key = valid_key?(key)
|
50
|
+
hash.define_singleton_method(valid_key) { self[key] }
|
51
|
+
hash.define_singleton_method("#{valid_key}=") do |value|
|
52
|
+
self[key] = value
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# This will output any warnings we want to output.
|
58
|
+
def self.handle_warnings(hash, key, override_warnings = false)
|
59
|
+
if !override_warnings && should_warn?(hash, key) then
|
60
|
+
if override_warnings.respond_to?(:puts) then
|
61
|
+
override_warnings.puts(should_warn?(hash, key))
|
62
|
+
else
|
63
|
+
raise ArgumentError, should_warn?(hash, key)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Returns a valid method name for the passed key if there is one, otherwise
|
70
|
+
# returns false.
|
71
|
+
def self.valid_key?(key)
|
72
|
+
regex_match = key.to_s.match(/\A[a-z_][a-z0-9_]*\Z/)
|
73
|
+
return false if regex_match.nil?
|
74
|
+
return key.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# If there should be a warning, returns the warning message. Otherwise returns
|
79
|
+
# false.
|
80
|
+
def self.should_warn?(hash, key)
|
81
|
+
valid_key = valid_key?(key)
|
82
|
+
|
83
|
+
# Make sure its a valid key...
|
84
|
+
return "#{key} is not a valid key." unless valid_key
|
85
|
+
# And make sure they don't have this method...
|
86
|
+
if hash.respond_to?(valid_key) then
|
87
|
+
return "#{hash} already has a #{valid_key} method defined."
|
88
|
+
end
|
89
|
+
if hash.respond_to?("#{valid_key}=") then
|
90
|
+
return "#{hash} already has a #{valid_key}= method defined."
|
91
|
+
end
|
92
|
+
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# This is an ugly ugly way of checking if the objectify method is defined
|
98
|
+
# somewhere already. For whatever reason :respond_to? is simply not returning
|
99
|
+
# the correct result.
|
100
|
+
if begin
|
101
|
+
method(:objectify)
|
102
|
+
true
|
103
|
+
rescue NameError
|
104
|
+
false
|
105
|
+
end then
|
106
|
+
|
107
|
+
unless HashToObj.const_defined?(:SQUELCH_GLOBAL_WARNINGS) then
|
108
|
+
puts 'Global already has an objectify method. '\
|
109
|
+
'Call HashToObj.objectify instead.'
|
110
|
+
end
|
111
|
+
else
|
112
|
+
def objectify(hash, override_warnings = false)
|
113
|
+
HashToObj.objectify(hash, override_warnings)
|
114
|
+
end
|
115
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hash-to-obj
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam Maxwell
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-16 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.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
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
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Call 'objectify my_hash' to add accessor methods to my_hash based on
|
70
|
+
the keys currently in the has.
|
71
|
+
email:
|
72
|
+
- raindropenter@gmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".travis.yml"
|
80
|
+
- Gemfile
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/setup
|
84
|
+
- hash-to-obj.gemspec
|
85
|
+
- lib/hash-to-obj.rb
|
86
|
+
- lib/hash-to-obj/version.rb
|
87
|
+
homepage: https://github.com/ReinAkane/hash-to-obj
|
88
|
+
licenses: []
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.5.1
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: Simple Ruby gem to objectify hashes
|
110
|
+
test_files: []
|