hash-access 0.1.0 → 0.2.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.
- data/LICENSE +1 -1
- data/README.md +58 -0
- data/Rakefile +20 -45
- data/lib/hash_access.rb +34 -18
- data/lib/hash_access/version.rb +4 -0
- data/spec/hash_access_spec.rb +91 -0
- metadata +20 -16
- data/README +0 -17
- data/test/test_hash_access.rb +0 -41
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# HashAccess
|
2
|
+
|
3
|
+
[HashAccess](https://github.com/slavach/hash-access) allows access to hash
|
4
|
+
elements by calling methods. When using HashAccess you can call a method
|
5
|
+
on a hash instance to get the corresponding value of a key.
|
6
|
+
|
7
|
+
You can write:
|
8
|
+
|
9
|
+
hash.some_key = 'something'
|
10
|
+
|
11
|
+
instead of:
|
12
|
+
|
13
|
+
hash['some_key'] = 'something'
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Hash access is available as the gem hash-access.
|
18
|
+
|
19
|
+
gem install hash-access
|
20
|
+
|
21
|
+
## Usage Example
|
22
|
+
|
23
|
+
require 'hash_access'
|
24
|
+
include HashAccess
|
25
|
+
|
26
|
+
h = {}
|
27
|
+
h.access_by_methods
|
28
|
+
h.first_key = 'First value' # the same as h['first_key'] = 'First value'
|
29
|
+
h.another_key = 'Another value' # the same as h['another_key'] = 'Another value'
|
30
|
+
|
31
|
+
## Development
|
32
|
+
|
33
|
+
Clone hash-access source from GitGub:
|
34
|
+
|
35
|
+
git clone git://github.com/slavach/hash-access.git
|
36
|
+
|
37
|
+
Install bundler if it has not been installed yet:
|
38
|
+
|
39
|
+
gem install bundler
|
40
|
+
|
41
|
+
Install additional gems for testing and documentation:
|
42
|
+
|
43
|
+
bundle install
|
44
|
+
|
45
|
+
The above command installs gems: rspec, rdoc, yard, BlueCloth.
|
46
|
+
|
47
|
+
To invoke tests - run `rake spec` or simply `rake`.
|
48
|
+
|
49
|
+
## Author
|
50
|
+
|
51
|
+
HashAccess has been written by Svetoslav Chernobay <slava@chernobay.info>.
|
52
|
+
Feel free to contact him if you have any questions or comments.
|
53
|
+
|
54
|
+
## Notes
|
55
|
+
|
56
|
+
HashAccess is a supplement module for UseConfig which is available at
|
57
|
+
GutHub [use-config](https://github.com/slavach/use-config) as well as the gem use-config.
|
58
|
+
|
data/Rakefile
CHANGED
@@ -1,63 +1,38 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
3
|
require 'rake/clean'
|
4
|
-
require 'rake/testtask'
|
5
4
|
require 'rake/rdoctask'
|
6
|
-
require 'rake/gempackagetask'
|
7
5
|
|
8
|
-
require '
|
6
|
+
require 'yard'
|
9
7
|
|
10
|
-
|
8
|
+
require 'rspec'
|
9
|
+
require 'rspec/core/rake_task'
|
11
10
|
|
12
|
-
|
11
|
+
require File.dirname(__FILE__) + "/lib/hash_access/version.rb"
|
13
12
|
|
14
|
-
|
15
|
-
task :readme do
|
16
|
-
%x[erb -T 1 README.erb > README] if File.exists?('README.erb')
|
17
|
-
end
|
13
|
+
task :default => [ :spec ]
|
18
14
|
|
19
|
-
|
20
|
-
task :rdoc => [ :readme ]
|
21
|
-
Rake::RDocTask.new do |rd|
|
22
|
-
rd.main = 'README'
|
23
|
-
rd.title = 'HashAccess'
|
24
|
-
rd.rdoc_dir = 'doc'
|
25
|
-
rd.template = 'jamis'
|
26
|
-
rd.options = %w[ --line-numbers --inline-source ]
|
27
|
-
rd.rdoc_files.include('README', 'LICENSE', 'lib/*.rb')
|
28
|
-
end
|
15
|
+
CLEAN.include(%w[ pkg doc .yardoc hash-access-*.gem ])
|
29
16
|
|
30
|
-
desc '
|
31
|
-
|
32
|
-
|
17
|
+
desc 'Run RSpec examples'
|
18
|
+
RSpec::Core::RakeTask.new :spec do |t|
|
19
|
+
t.rspec_opts = "--colour --format documentation"
|
20
|
+
t.pattern = 'spec/*.rb'
|
33
21
|
end
|
34
22
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
t.verbose = true
|
23
|
+
desc "Build the gem"
|
24
|
+
task :build do
|
25
|
+
system "gem build hash-access.gemspec"
|
39
26
|
end
|
40
27
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
s.platform = Gem::Platform::RUBY
|
45
|
-
s.has_rdoc = true
|
46
|
-
s.extra_rdoc_files = %w[ README LICENSE ]
|
47
|
-
s.rdoc_options = %w[ --main=README --line-numbers --inline-source ]
|
48
|
-
s.summary = 'HashAccess. Allows access to hash elements by methods.'
|
49
|
-
s.description = s.summary
|
50
|
-
s.author = 'Slava Chernobai'
|
51
|
-
s.email = 'chernobai@gmail.com'
|
52
|
-
s.homepage = 'http://code.slava.pp.ru/hash-access/'
|
53
|
-
s.files = %w[ README LICENSE Rakefile ] + Dir.glob("{lib,test}/*")
|
54
|
-
s.require_path = 'lib'
|
28
|
+
desc "Push the gem to rubygems.org"
|
29
|
+
task :push do
|
30
|
+
system "gem push hash-access-#{HashAccess::VERSION}.gem"
|
55
31
|
end
|
56
32
|
|
57
|
-
|
58
|
-
Rake::
|
59
|
-
|
60
|
-
|
61
|
-
p.need_zip = true
|
33
|
+
desc "Generate documentation"
|
34
|
+
YARD::Rake::YardocTask.new :doc do |t|
|
35
|
+
t.files = %w[ README.md, LICENSE, lib/**/*.rb ]
|
36
|
+
t.options = %w[ --title HashAccess ]
|
62
37
|
end
|
63
38
|
|
data/lib/hash_access.rb
CHANGED
@@ -1,45 +1,56 @@
|
|
1
|
-
|
2
|
-
VERSION = '0.1.0'
|
1
|
+
require 'hash_access/version'
|
3
2
|
|
3
|
+
module HashAccess # :nodoc:
|
4
|
+
# Extends the Hash class with the access_by_methods method.
|
4
5
|
def self.included(base)
|
5
6
|
Hash.send :include, HashAccess::InstanceMethods
|
6
7
|
end
|
7
8
|
|
8
|
-
# This module contains
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# thinks :)
|
9
|
+
# This module contains one method - access_by_methods instance method.
|
10
|
+
# The access_by_methods is added to Hash when the module HashAccess
|
11
|
+
# is being included.
|
12
|
+
# When the access_by_methods is being called it generates a couple of
|
13
|
+
# instance methods of the calling object:
|
14
14
|
#
|
15
|
-
#
|
15
|
+
# * access_by_methods?
|
16
16
|
# * store, []=
|
17
17
|
# * method_missing
|
18
18
|
# * stringify_keys!
|
19
19
|
module InstanceMethods
|
20
|
-
# Generates singleton instance methods
|
21
|
-
#
|
20
|
+
# Generates singleton instance methods that allows access to any hash
|
21
|
+
# element using a method with the same name as the key.
|
22
|
+
# Recursively calls itlelf on child hashes.
|
22
23
|
def access_by_methods
|
24
|
+
return self if self.respond_to? :access_by_methods? and self.access_by_methods?
|
23
25
|
class << self
|
24
26
|
alias_method :__hash_store, :store
|
25
27
|
alias_method :__hash_assign, :[]=
|
26
28
|
|
27
|
-
# Generated instance method.
|
29
|
+
# Generated instance method.
|
30
|
+
# Hash elements can be accessed using methods.
|
31
|
+
def access_by_methods?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generated instance method.
|
36
|
+
# Stores a key-value pair.
|
28
37
|
def store(key, value)
|
29
|
-
key = key.to_s
|
30
|
-
__hash_store(key, value)
|
31
38
|
if value.is_a? Hash
|
32
39
|
value.access_by_methods
|
33
40
|
end
|
41
|
+
key = key.to_s
|
42
|
+
__hash_store(key, value)
|
34
43
|
end # def store
|
35
44
|
|
36
|
-
# Generated instance method.
|
45
|
+
# Generated instance method.
|
46
|
+
# Stores a key-value pair.
|
37
47
|
def []=(key, value)
|
38
48
|
self.store(key, value)
|
39
49
|
end # def []=
|
40
50
|
|
41
51
|
# Generated instance method.
|
42
|
-
# Creates new hash element with the
|
52
|
+
# Creates a new hash element with a key is the same as the passed
|
53
|
+
# method.
|
43
54
|
def method_missing(method, *values)
|
44
55
|
method_name = method.to_s
|
45
56
|
super(method, *values) unless method_name =~ /^[a-z0-9]+.*$/
|
@@ -51,12 +62,14 @@ module HashAccess # :nodoc:
|
|
51
62
|
self[key] = values
|
52
63
|
end
|
53
64
|
else
|
54
|
-
self[method_name] = Hash.new
|
65
|
+
self[method_name] = Hash.new.access_by_methods \
|
66
|
+
unless self.keys.include?(method_name)
|
55
67
|
self[method_name]
|
56
68
|
end
|
57
69
|
end # def method_missing
|
58
70
|
|
59
|
-
# Generated instance method.
|
71
|
+
# Generated instance method.
|
72
|
+
# Converts all hash keys to strings.
|
60
73
|
def stringify_keys!
|
61
74
|
keys.each do |key|
|
62
75
|
next if key.is_a? String
|
@@ -69,11 +82,14 @@ module HashAccess # :nodoc:
|
|
69
82
|
|
70
83
|
self.stringify_keys!
|
71
84
|
|
85
|
+
# Recursive calls
|
72
86
|
self.each do |key, value|
|
73
87
|
if value.is_a? Hash
|
74
88
|
value.access_by_methods
|
75
89
|
end
|
76
90
|
end
|
91
|
+
|
92
|
+
self
|
77
93
|
end # def access_by_methods
|
78
94
|
end # module InstanceMethods
|
79
95
|
end # module HashAccess
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require File.dirname(__FILE__) + "/../lib/hash_access.rb"
|
3
|
+
include HashAccess
|
4
|
+
|
5
|
+
describe HashAccess do
|
6
|
+
describe "new empty Hash instance" do
|
7
|
+
it "responds to :access_by_methods" do
|
8
|
+
@hash = Hash.new
|
9
|
+
@hash.respond_to?(:access_by_methods).should == true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "new empty Hash instance after the call to access_by_methods" do
|
14
|
+
before :each do
|
15
|
+
@hash = Hash.new
|
16
|
+
@hash.access_by_methods
|
17
|
+
end
|
18
|
+
|
19
|
+
it "responds to :access_by_methods?" do
|
20
|
+
@hash.respond_to?(:access_by_methods?).should == true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "responds to :stringify_keys!" do
|
24
|
+
@hash.respond_to?(:stringify_keys!).should == true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "non-empty Hash instance after the call to access_by_methods" do
|
29
|
+
before :each do
|
30
|
+
@hash = Hash.new
|
31
|
+
@hash[:qwe] = 'qwe_value'
|
32
|
+
@hash[:asd] = {}
|
33
|
+
@hash[:asd][:fgh] = :asd_fgh_value
|
34
|
+
@hash['zxc'] = {}
|
35
|
+
@hash['zxc']['vbn'] = 'zxc_vbn_value'
|
36
|
+
@hash.access_by_methods
|
37
|
+
end
|
38
|
+
|
39
|
+
it "changes symbol-type keys to strings" do
|
40
|
+
@hash.keys.sort.should == %w( asd qwe zxc )
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns a value when being call to a method" do
|
44
|
+
@hash.qwe.should == 'qwe_value'
|
45
|
+
@hash.asd.fgh.should == :asd_fgh_value
|
46
|
+
@hash.zxc.vbn.should == 'zxc_vbn_value'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "changes a value" do
|
50
|
+
@hash.qwe = 'new_qwe_value'
|
51
|
+
@hash.qwe.should == 'new_qwe_value'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "creates a new value when being call to a method" do
|
55
|
+
@hash.qwerty.asdfgh.zxcvbn = 'qwertyuiop'
|
56
|
+
@hash.qwerty.asdfgh.zxcvbn.should == 'qwertyuiop'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "replaces the existing value" do
|
60
|
+
@hash.qwe = 'new_qwe_value'
|
61
|
+
@hash.qwe.should == 'new_qwe_value'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "it replaces the existing parent element" do
|
65
|
+
@hash.qwerty.asdfgh.zxcvbn.qwerty.asdfgh.zxcvbn = 'qwertyuiop'
|
66
|
+
@hash.qwerty.asdfgh.zxcvbn = 'qwerty_asdfgh_zxcvbn'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "child hash" do
|
71
|
+
before :each do
|
72
|
+
@hash = {}
|
73
|
+
@hash.access_by_methods
|
74
|
+
@hash.qwe.asd = 'qwe_asd_value'
|
75
|
+
@child = @hash.qwe
|
76
|
+
end
|
77
|
+
it "responds to access_by_methods?" do
|
78
|
+
@child.respond_to?(:access_by_methods?).should == true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns a value when being call to a method" do
|
82
|
+
@child.asd.should == 'qwe_asd_value'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "creates a new element when being call to a method" do
|
86
|
+
@child.zxc = 'zxc_value'
|
87
|
+
@child.zxc.should == 'zxc_value'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
metadata
CHANGED
@@ -1,35 +1,39 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash-access
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.1
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
|
-
-
|
8
|
+
- Svetoslav Chernobay
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
12
|
|
12
|
-
date:
|
13
|
+
date: 2011-03-08 00:00:00 +03:00
|
13
14
|
default_executable:
|
14
15
|
dependencies: []
|
15
16
|
|
16
|
-
description: HashAccess
|
17
|
-
email:
|
17
|
+
description: HashAccess library allows access to hash elements by calling methods
|
18
|
+
email: slava@chernobay.info
|
18
19
|
executables: []
|
19
20
|
|
20
21
|
extensions: []
|
21
22
|
|
22
23
|
extra_rdoc_files:
|
23
|
-
- README
|
24
|
+
- README.md
|
24
25
|
- LICENSE
|
25
26
|
files:
|
26
|
-
- README
|
27
|
+
- README.md
|
27
28
|
- LICENSE
|
28
29
|
- Rakefile
|
29
30
|
- lib/hash_access.rb
|
30
|
-
-
|
31
|
+
- lib/hash_access/version.rb
|
32
|
+
- spec/hash_access_spec.rb
|
31
33
|
has_rdoc: true
|
32
|
-
homepage: http://
|
34
|
+
homepage: http://github.com/slavach/hash-access
|
35
|
+
licenses: []
|
36
|
+
|
33
37
|
post_install_message:
|
34
38
|
rdoc_options:
|
35
39
|
- --main=README
|
@@ -38,23 +42,23 @@ rdoc_options:
|
|
38
42
|
require_paths:
|
39
43
|
- lib
|
40
44
|
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
41
46
|
requirements:
|
42
47
|
- - ">="
|
43
48
|
- !ruby/object:Gem::Version
|
44
49
|
version: "0"
|
45
|
-
version:
|
46
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
47
52
|
requirements:
|
48
53
|
- - ">="
|
49
54
|
- !ruby/object:Gem::Version
|
50
|
-
version:
|
51
|
-
version:
|
55
|
+
version: 1.3.6
|
52
56
|
requirements: []
|
53
57
|
|
54
|
-
rubyforge_project:
|
55
|
-
rubygems_version: 1.
|
58
|
+
rubyforge_project: hash-access
|
59
|
+
rubygems_version: 1.5.2
|
56
60
|
signing_key:
|
57
|
-
specification_version:
|
58
|
-
summary:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Allows access to hash elements by methods
|
59
63
|
test_files: []
|
60
64
|
|
data/README
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
== HashAccess 0.1.0
|
2
|
-
This library allows access to hash elements by methods.
|
3
|
-
|
4
|
-
Install:
|
5
|
-
|
6
|
-
gem ins hash-access
|
7
|
-
|
8
|
-
Usage example:
|
9
|
-
|
10
|
-
require 'hash_access'
|
11
|
-
include HashAccess
|
12
|
-
|
13
|
-
h = Hash.new
|
14
|
-
h.access_by_methods
|
15
|
-
h.one.two.three = 'qwe'
|
16
|
-
print(h.inspect, "\n") # => {"one"=>{"two"=>{"three"=>"qwe"}}}=> nil
|
17
|
-
|
data/test/test_hash_access.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'hash_access'
|
3
|
-
|
4
|
-
class HashAccessTest < Test::Unit::TestCase
|
5
|
-
def setup
|
6
|
-
self.class.send :include, HashAccess
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_001_hash_must_respond_to_access_by_methods
|
10
|
-
hash = {}
|
11
|
-
assert_respond_to(hash, :access_by_methods)
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_002_access_by_methods_generates_methods
|
15
|
-
hash_abm = {}
|
16
|
-
hash_abm.access_by_methods
|
17
|
-
assert_respond_to(hash_abm, :stringify_keys!)
|
18
|
-
assert_respond_to(hash_abm, :__hash_store)
|
19
|
-
assert_respond_to(hash_abm, :__hash_assign)
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_003_changes_existing_hash_instance
|
23
|
-
hash_abm = {}
|
24
|
-
hash_abm['first'] = {}
|
25
|
-
hash_abm['first']['one'] = :first_one
|
26
|
-
hash_abm[:second] = {}
|
27
|
-
hash_abm[:second][:one] = :second_one
|
28
|
-
hash_abm.access_by_methods
|
29
|
-
assert_equal(hash_abm.keys.sort, %w[ first second ])
|
30
|
-
assert_equal(hash_abm.first.one, :first_one)
|
31
|
-
assert_equal(hash_abm.second.one, :second_one)
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_004_creates_new_element_and_parent_hashes
|
35
|
-
hash_abm = {}
|
36
|
-
hash_abm.access_by_methods
|
37
|
-
hash_abm.first.second.third.fourth = :first_second_third_fourth
|
38
|
-
assert_equal(hash_abm['first']['second']['third']['fourth'], hash_abm.first.second.third.fourth)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|