hash-ninja 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.
- data/.gitignore +6 -0
- data/Gemfile +6 -0
- data/Rakefile +1 -0
- data/hashninja.gemspec +21 -0
- data/lib/hash_ninja.rb +10 -0
- data/lib/hash_ninja/active_hash.rb +127 -0
- data/lib/hash_ninja/core_ext.rb +50 -0
- data/lib/hash_ninja/hash_attr_reader.rb +37 -0
- data/lib/hash_ninja/version.rb +5 -0
- data/spec/hash_ninja/active_hash_spec.rb +26 -0
- data/spec/hash_ninja/core_ext_spec.rb +86 -0
- data/spec/hash_ninja/hash_attr_reader_spec.rb +66 -0
- data/spec/hash_ninja/usage_spec.rb +46 -0
- metadata +78 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/hashninja.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "hash_ninja/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "hash-ninja"
|
7
|
+
s.version = HashNinja::VERSION
|
8
|
+
s.authors = ["Kazuhiro Sera"]
|
9
|
+
s.email = ["seratch@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/seratch/hash-ninja"
|
11
|
+
s.summary = %q{Hash toolkit for Ruby ninja}
|
12
|
+
s.description = %q{Hash toolkit for Ruby ninja}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_runtime_dependency "activesupport"
|
20
|
+
|
21
|
+
end
|
data/lib/hash_ninja.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "hash_ninja"
|
4
|
+
require "active_support/core_ext/hash/keys"
|
5
|
+
|
6
|
+
module HashNinja
|
7
|
+
|
8
|
+
# Hash with extended ActiveSupport
|
9
|
+
#
|
10
|
+
# See also {active_support/core_ext/hash/keys}[http://as.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
|
11
|
+
module ActiveHash
|
12
|
+
|
13
|
+
# Applies ActiveSupport::Inflector.underscore to all the Hash#keys destructively.
|
14
|
+
# Keys should be either Symbol or String.
|
15
|
+
#
|
16
|
+
# ==== Examples
|
17
|
+
# hash = {:rubyOnRails => 'http://rubyonrails.org/'}
|
18
|
+
# has.activate!.underscore_keys! # => {:ruby_on_rails => 'http://rubyonrails.org/'}
|
19
|
+
def underscore_keys!
|
20
|
+
self.keys.each do |key|
|
21
|
+
value = delete(key)
|
22
|
+
if key.is_a? String
|
23
|
+
self[key.underscore] = value
|
24
|
+
elsif key.is_a? Symbol
|
25
|
+
self[key.to_s.underscore.to_sym] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
# Applies ActiveSupport::Inflector#classify to all the Hash#keys destructively.
|
32
|
+
# Keys should be either Symbol or String.
|
33
|
+
#
|
34
|
+
# ==== Examples
|
35
|
+
# hash = {:ruby_on_rails => 'http://rubyonrails.org/'}
|
36
|
+
# has.activate!.classify_keys! # => {:RubyOnRails => 'http://rubyonrails.org/'}
|
37
|
+
def classify_keys!
|
38
|
+
self.keys.each do |key|
|
39
|
+
value = delete(key)
|
40
|
+
if key.is_a? String
|
41
|
+
self[key.classify] = value
|
42
|
+
elsif key.is_a? Symbol
|
43
|
+
self[key.to_s.classify.to_sym] = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Applies ActiveSupport::Inflector#camelize to all the Hash#keys destructively.
|
49
|
+
# Keys should be either Symbol or String.
|
50
|
+
#
|
51
|
+
# ==== Examples
|
52
|
+
# hash = {:ruby_on_rails => 'http://rubyonrails.org/'}
|
53
|
+
# has.activate!.camelize_keys! # => {:RubyOnRails => 'http://rubyonrails.org/'}
|
54
|
+
def camelize_keys!
|
55
|
+
self.keys.each do |key|
|
56
|
+
value = delete(key)
|
57
|
+
if key.is_a? String
|
58
|
+
self[key.camelize] = value
|
59
|
+
elsif key.is_a? Symbol
|
60
|
+
self[key.to_s.camelize.to_sym] = value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Applies ActiveSupport::Inflector#camelize(:lower) to all the Hash#keys destructively.
|
67
|
+
# Keys should be either Symbol or String.
|
68
|
+
#
|
69
|
+
# ==== Examples
|
70
|
+
# hash = {:ruby_on_rails => 'http://rubyonrails.org/'}
|
71
|
+
# has.activate!.camelize_lower_keys! # => {:rubyOnRails => 'http://rubyonrails.org/'}
|
72
|
+
def camelize_lower_keys!
|
73
|
+
self.keys.each do |key|
|
74
|
+
value = delete(key)
|
75
|
+
if key.is_a? String
|
76
|
+
self[key.camelize(:lower)] = value
|
77
|
+
elsif key.is_a? Symbol
|
78
|
+
self[key.to_s.camelize(:lower).to_sym] = value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Provides the following recursive methods.
|
84
|
+
#
|
85
|
+
# ====
|
86
|
+
# * recursively_camelize_keys!
|
87
|
+
# * recursively_camelize_lower_keys!
|
88
|
+
# * recursively_classify_keys!
|
89
|
+
# * recursively_underscore_keys!
|
90
|
+
def method_missing(name, *args, &block)
|
91
|
+
# provides 'recursively_xxx' methods
|
92
|
+
if name.match(/recursively_/)
|
93
|
+
method_name = name.to_s.sub(/^recursively_/, '')
|
94
|
+
self.public_send(method_name, *args, &block)
|
95
|
+
self.values.each do |value|
|
96
|
+
if value.is_a? Hash
|
97
|
+
value.extend HashNinja::ActiveHash
|
98
|
+
value.public_send(name, *args, &block)
|
99
|
+
elsif value.is_a? Array
|
100
|
+
value.public_send(name, *args, &block)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
self
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Array
|
111
|
+
def method_missing(name, *args, &block)
|
112
|
+
# for ActiveHash#recursively_xxx
|
113
|
+
if name.match(/recursively_/)
|
114
|
+
method_name = name.to_s.sub(/^recursively_/, '')
|
115
|
+
self.each do |value|
|
116
|
+
if value.is_a? Hash
|
117
|
+
value.extend HashNinja::ActiveHash
|
118
|
+
value.public_send(name, *args, &block)
|
119
|
+
elsif value.is_a? Array
|
120
|
+
value.public_send(name, *args, &block)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
self
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "hash_ninja"
|
4
|
+
require "active_support/core_ext/string/inflections"
|
5
|
+
|
6
|
+
module HashNinja
|
7
|
+
module CoreExt
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Hash
|
12
|
+
|
13
|
+
# Updates itself as HashNinja::ActiveHash destructively. 'active_support' will be also applied.
|
14
|
+
def activate!
|
15
|
+
self.extend HashNinja::ActiveHash
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Provides HashNinja::HashAccessor object
|
20
|
+
def to_attr_reader
|
21
|
+
HashNinja::HashAttrReader.new(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Creates Hash object which contains the readable instance variables of 'obj'.
|
25
|
+
# It's possible to customize the key convention by 'key_strategy'.
|
26
|
+
def self.from_attr(obj, key_strategy = :underscore)
|
27
|
+
hash = {}
|
28
|
+
obj.instance_variables.each do |attr|
|
29
|
+
original_key = attr.to_s.delete('@')
|
30
|
+
case key_strategy
|
31
|
+
when :underscore
|
32
|
+
key = original_key.underscore
|
33
|
+
when :camelize
|
34
|
+
key = original_key.camelize
|
35
|
+
when :camelize_lower
|
36
|
+
key = original_key.camelize(:lower)
|
37
|
+
when :classify
|
38
|
+
key = original_key.classify
|
39
|
+
else
|
40
|
+
key = original_key
|
41
|
+
end
|
42
|
+
begin
|
43
|
+
hash[key.to_sym] = obj.send(original_key.to_sym)
|
44
|
+
rescue NoMethodError => e
|
45
|
+
end
|
46
|
+
end
|
47
|
+
hash
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module HashNinja
|
4
|
+
|
5
|
+
# Provides attr_reader Hash data
|
6
|
+
# ==== Examples
|
7
|
+
# member = {'name'=>'Andy', 'type' => { 'id' => 999, 'name' => 'Guest' }}.to_attr_reader
|
8
|
+
# member.name # => 'Andy'
|
9
|
+
# member.type.id # => 999
|
10
|
+
class HashAttrReader
|
11
|
+
# target Hash object
|
12
|
+
attr_reader :hash
|
13
|
+
|
14
|
+
# The 'hash' should be a Hash object.
|
15
|
+
def initialize(hash)
|
16
|
+
raise "hash should be a Hash object #{hash.to_s}" unless hash.is_a? Hash
|
17
|
+
@hash = hash
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(name, *args, &block)
|
21
|
+
found = @hash[name] || @hash[name.to_s]
|
22
|
+
if found
|
23
|
+
if found.is_a? Hash
|
24
|
+
found.to_attr_reader
|
25
|
+
else
|
26
|
+
found
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the Hash object held internally
|
32
|
+
def to_hash
|
33
|
+
@hash
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'hash_ninja'
|
5
|
+
|
6
|
+
describe HashNinja::ActiveHash do
|
7
|
+
|
8
|
+
it 'should have #underscore_keys!' do
|
9
|
+
hash = {:rubyOnRails => 'xxx', 'ProgrammingRuby' => {'RubyGems' => 'yyy'}}
|
10
|
+
hash.activate!.underscore_keys!
|
11
|
+
|
12
|
+
hash[:ruby_on_rails].should eq('xxx')
|
13
|
+
hash['programming_ruby'].should eq({'RubyGems' => 'yyy'})
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should have #recursively_underscore_keys!' do
|
17
|
+
hash = {:rubyOnRails => 'aaa', 'ProgrammingRuby' => {:RubyGems => 'bbb', 'rubyMine' => 'ccc'}}
|
18
|
+
hash.activate!.recursively_underscore_keys!
|
19
|
+
|
20
|
+
hash[:ruby_on_rails].should eq('aaa')
|
21
|
+
hash['programming_ruby'].should eq({:ruby_gems => 'bbb', 'ruby_mine' => 'ccc'})
|
22
|
+
hash['programming_ruby'][:ruby_gems].should eq('bbb')
|
23
|
+
hash['programming_ruby']['ruby_mine'].should eq('ccc')
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'hash_ninja'
|
4
|
+
|
5
|
+
describe Hash do
|
6
|
+
|
7
|
+
it 'should have #activate!' do
|
8
|
+
activated = {:first => 'aaa', 'second' => 'bbb'}.activate!
|
9
|
+
activated.is_a?(HashNinja::ActiveHash).should eq(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
class Member
|
13
|
+
attr_accessor :id
|
14
|
+
attr_accessor :name
|
15
|
+
attr_accessor :age
|
16
|
+
|
17
|
+
def initialize(id, name, age)
|
18
|
+
@id = id
|
19
|
+
@name = name
|
20
|
+
@age = age
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Member2Underscore
|
25
|
+
attr_accessor :firstName
|
26
|
+
attr_accessor :lastName
|
27
|
+
|
28
|
+
def initialize(firstName, lastName)
|
29
|
+
@firstName = firstName
|
30
|
+
@lastName = lastName
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Member2Camelize
|
35
|
+
attr_accessor :first_name
|
36
|
+
attr_accessor :last_name
|
37
|
+
|
38
|
+
def initialize(first_name, last_name)
|
39
|
+
@first_name = first_name
|
40
|
+
@last_name = last_name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'shoud have from_attr' do
|
45
|
+
andy = Member.new(123, 'Andy', 20)
|
46
|
+
andy_hash = Hash.from_attr(andy)
|
47
|
+
andy_hash[:id].should eq(123)
|
48
|
+
andy_hash[:name].should eq('Andy')
|
49
|
+
andy_hash[:age].should eq(20)
|
50
|
+
|
51
|
+
brian = Member.new(123, 'Brian', nil)
|
52
|
+
brian_hash = Hash.from_attr(brian)
|
53
|
+
brian_hash[:id].should eq(123)
|
54
|
+
brian_hash[:name].should eq('Brian')
|
55
|
+
brian_hash[:age].should eq(nil)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should have from_attr (underscore)' do
|
59
|
+
m = Member2Underscore.new('Linus', 'Torvalds')
|
60
|
+
hash = Hash.from_attr(m, :underscore)
|
61
|
+
hash[:first_name].should eq('Linus')
|
62
|
+
hash[:last_name].should eq('Torvalds')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should have from_attr (camelize)' do
|
66
|
+
m = Member2Camelize.new('Linus', 'Torvalds')
|
67
|
+
hash = Hash.from_attr(m, :camelize)
|
68
|
+
hash[:FirstName].should eq('Linus')
|
69
|
+
hash[:LastName].should eq('Torvalds')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should have from_attr (camelize_lower)' do
|
73
|
+
m = Member2Camelize.new('Linus', 'Torvalds')
|
74
|
+
hash = Hash.from_attr(m, :camelize_lower)
|
75
|
+
hash[:firstName].should eq('Linus')
|
76
|
+
hash[:lastName].should eq('Torvalds')
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should have from_attr (classify)' do
|
80
|
+
m = Member2Camelize.new('Linus', 'Torvalds')
|
81
|
+
hash = Hash.from_attr(m, :classify)
|
82
|
+
hash[:FirstName].should eq('Linus')
|
83
|
+
hash[:LastName].should eq('Torvalds')
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "hash_ninja"
|
4
|
+
|
5
|
+
describe HashNinja::HashAttrReader do
|
6
|
+
|
7
|
+
it 'should work with string keys' do
|
8
|
+
hash = {:something => 'like that', :name => 'hash_ninja'}
|
9
|
+
hash_attr = hash.to_attr_reader
|
10
|
+
|
11
|
+
hash_attr.something.should eq('like that')
|
12
|
+
hash_attr.name.should eq('hash_ninja')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should work with symbol keys' do
|
16
|
+
hash = {:something => 'like that', :name => 'hash_ninja'}
|
17
|
+
hash_attr = hash.to_attr_reader
|
18
|
+
|
19
|
+
hash_attr.something.should eq('like that')
|
20
|
+
hash_attr.name.should eq('hash_ninja')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should work with nested hash' do
|
24
|
+
hash = {
|
25
|
+
:something => 'like that',
|
26
|
+
:nested => {
|
27
|
+
:name => 'hash_ninja',
|
28
|
+
:since => 2012
|
29
|
+
}
|
30
|
+
}
|
31
|
+
hash_attr = hash.to_attr_reader
|
32
|
+
|
33
|
+
hash_attr.something.should eq('like that')
|
34
|
+
hash_attr.nested.name.should eq('hash_ninja')
|
35
|
+
hash_attr.nested.since.should eq(2012)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should work with keys which contains whitespace' do
|
39
|
+
hash = {'contains whitespace' => 'like that'}
|
40
|
+
hash_attr = hash.to_attr_reader
|
41
|
+
|
42
|
+
hash_attr.contains_whitespace.should eq(nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should work with string keys' do
|
46
|
+
hash = {'something' => 'like that', 'name' => 'hash_ninja'}
|
47
|
+
hash_attr = hash.to_attr_reader
|
48
|
+
|
49
|
+
hash_attr.something.should eq('like that')
|
50
|
+
hash_attr.name.should eq('hash_ninja')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should work with array' do
|
54
|
+
hash = {
|
55
|
+
'str_array' => ['a', 'b', 'c'],
|
56
|
+
'hash_array' => [{:a => 1}, {:aa => 1, :bb => 2}],
|
57
|
+
'nested' => {'array' => [1, 2, 3]}
|
58
|
+
}
|
59
|
+
hash_attr = hash.to_attr_reader
|
60
|
+
|
61
|
+
hash_attr.str_array.should eq(['a', 'b', 'c'])
|
62
|
+
hash_attr.hash_array.should eq([{:a => 1}, {:aa => 1, :bb => 2}])
|
63
|
+
hash_attr.nested.array.should eq([1, 2, 3])
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'hash_ninja'
|
5
|
+
|
6
|
+
describe HashNinja do
|
7
|
+
|
8
|
+
it 'should work with the Google+ API example data' do
|
9
|
+
google_plus_api_example = <<JSON
|
10
|
+
{
|
11
|
+
"kind": "plus#person",
|
12
|
+
"id": "118051310819094153327",
|
13
|
+
"displayName": "Chirag Shah",
|
14
|
+
"url": "https://plus.google.com/118051310819094153327",
|
15
|
+
"image": {
|
16
|
+
"url": "https://lh5.googleusercontent.com/-XnZDEoiF09Y/AAAAAAAAAAI/AAAAAAAAYCI/7fow4a2UTMU/photo.jpg"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
JSON
|
20
|
+
|
21
|
+
hash = ActiveSupport::JSON.decode(google_plus_api_example)
|
22
|
+
hash.activate!
|
23
|
+
|
24
|
+
hash.recursively_underscore_keys!
|
25
|
+
hash['kind'].should eq('plus#person')
|
26
|
+
hash['id'].should eq('118051310819094153327')
|
27
|
+
hash['display_name'].should eq('Chirag Shah')
|
28
|
+
hash['url'].should eq('https://plus.google.com/118051310819094153327')
|
29
|
+
hash['image']['url'].should eq('https://lh5.googleusercontent.com/-XnZDEoiF09Y/AAAAAAAAAAI/AAAAAAAAYCI/7fow4a2UTMU/photo.jpg')
|
30
|
+
|
31
|
+
hash.recursively_symbolize_keys!
|
32
|
+
hash[:kind].should eq('plus#person')
|
33
|
+
hash[:id].should eq('118051310819094153327')
|
34
|
+
hash[:display_name].should eq('Chirag Shah')
|
35
|
+
hash[:url].should eq('https://plus.google.com/118051310819094153327')
|
36
|
+
hash[:image][:url].should eq('https://lh5.googleusercontent.com/-XnZDEoiF09Y/AAAAAAAAAAI/AAAAAAAAYCI/7fow4a2UTMU/photo.jpg')
|
37
|
+
|
38
|
+
hash_attr = hash.to_attr_reader
|
39
|
+
hash_attr.kind.should eq('plus#person')
|
40
|
+
hash_attr.id.should eq('118051310819094153327')
|
41
|
+
hash_attr.display_name.should eq('Chirag Shah')
|
42
|
+
hash_attr.url.should eq('https://plus.google.com/118051310819094153327')
|
43
|
+
hash_attr.image.url.should eq('https://lh5.googleusercontent.com/-XnZDEoiF09Y/AAAAAAAAAAI/AAAAAAAAYCI/7fow4a2UTMU/photo.jpg')
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hash-ninja
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kazuhiro Sera
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Hash toolkit for Ruby ninja
|
31
|
+
email:
|
32
|
+
- seratch@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- Rakefile
|
40
|
+
- hashninja.gemspec
|
41
|
+
- lib/hash_ninja.rb
|
42
|
+
- lib/hash_ninja/active_hash.rb
|
43
|
+
- lib/hash_ninja/core_ext.rb
|
44
|
+
- lib/hash_ninja/hash_attr_reader.rb
|
45
|
+
- lib/hash_ninja/version.rb
|
46
|
+
- spec/hash_ninja/active_hash_spec.rb
|
47
|
+
- spec/hash_ninja/core_ext_spec.rb
|
48
|
+
- spec/hash_ninja/hash_attr_reader_spec.rb
|
49
|
+
- spec/hash_ninja/usage_spec.rb
|
50
|
+
homepage: https://github.com/seratch/hash-ninja
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.21
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Hash toolkit for Ruby ninja
|
74
|
+
test_files:
|
75
|
+
- spec/hash_ninja/active_hash_spec.rb
|
76
|
+
- spec/hash_ninja/core_ext_spec.rb
|
77
|
+
- spec/hash_ninja/hash_attr_reader_spec.rb
|
78
|
+
- spec/hash_ninja/usage_spec.rb
|