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.
@@ -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
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hash-to-obj.gemspec
4
+ gemspec
@@ -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.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :test_dsl do
7
+ ruby "spec/hash-to-obj_helper.rb"
8
+ end
9
+
10
+ task :default => [:spec, :test_dsl]
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ module HashToObj
2
+ VERSION = '0.1.0'.freeze
3
+ 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: []