hashie 0.1.8 → 0.2.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/README.rdoc +28 -8
- data/VERSION +1 -1
- data/hashie.gemspec +7 -4
- data/lib/hashie.rb +2 -1
- data/lib/hashie/clash.rb +86 -0
- data/spec/hashie/clash_spec.rb +42 -0
- metadata +21 -9
data/README.rdoc
CHANGED
@@ -4,14 +4,8 @@ Hashie is a growing collection of tools that extend Hashes and make
|
|
4
4
|
them more useful.
|
5
5
|
|
6
6
|
== Installation
|
7
|
-
|
8
|
-
Hashie is a gem and is available on Gemcutter. If you don't have Gemcutter,
|
9
|
-
install it:
|
10
|
-
|
11
|
-
gem install gemcutter
|
12
|
-
gem tumble
|
13
7
|
|
14
|
-
|
8
|
+
Hashie is available as a RubyGem:
|
15
9
|
|
16
10
|
gem install hashie
|
17
11
|
|
@@ -62,7 +56,33 @@ can set defaults for each property.
|
|
62
56
|
p = Person.new(:name => "Bob")
|
63
57
|
p.name # => 'Bob'
|
64
58
|
p.occupation # => 'Rubyist'
|
65
|
-
|
59
|
+
|
60
|
+
== Clash
|
61
|
+
|
62
|
+
Clash is a Chainable Lazy Hash that allows you to easily construct
|
63
|
+
complex hashes using method notation chaining. This will allow you
|
64
|
+
to use a more action-oriented approach to building options hashes.
|
65
|
+
|
66
|
+
Essentially, a Clash is a generalized way to provide much of the same
|
67
|
+
kind of "chainability" that libraries like Arel or Rails 2.x's named_scopes
|
68
|
+
provide.
|
69
|
+
|
70
|
+
=== Example
|
71
|
+
|
72
|
+
c = Hashie::Clash.new
|
73
|
+
c.where(:abc => 'def').order(:created_at)
|
74
|
+
c # => {:where => {:abc => 'def}, :order => :created_at}
|
75
|
+
|
76
|
+
# You can also use bang notation to chain into sub-hashes,
|
77
|
+
# jumping back up the chain with _end!
|
78
|
+
c = Hashie::Clash.new
|
79
|
+
c.where!.abc('def').ghi(123)._end!.order(:created_at)
|
80
|
+
c # => {:where => {:abc => 'def', :ghi => 123}, :order => :created_at}
|
81
|
+
|
82
|
+
# Multiple hashes are merged automatically
|
83
|
+
c = Hashie::Clash.new
|
84
|
+
c.where(:abc => 'def').where(:hgi => 123)
|
85
|
+
c # => {:where => {:abc => 'def', :hgi => 123}}
|
66
86
|
|
67
87
|
== Note on Patches/Pull Requests
|
68
88
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/hashie.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hashie}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Bleigh"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-03-05}
|
13
13
|
s.description = %q{Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).}
|
14
14
|
s.email = %q{michael@intridea.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,10 +25,12 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"hashie.gemspec",
|
27
27
|
"lib/hashie.rb",
|
28
|
+
"lib/hashie/clash.rb",
|
28
29
|
"lib/hashie/dash.rb",
|
29
30
|
"lib/hashie/hash.rb",
|
30
31
|
"lib/hashie/hash_extensions.rb",
|
31
32
|
"lib/hashie/mash.rb",
|
33
|
+
"spec/hashie/clash_spec.rb",
|
32
34
|
"spec/hashie/dash_spec.rb",
|
33
35
|
"spec/hashie/hash_spec.rb",
|
34
36
|
"spec/hashie/mash_spec.rb",
|
@@ -38,10 +40,11 @@ Gem::Specification.new do |s|
|
|
38
40
|
s.homepage = %q{http://github.com/intridea/hashie}
|
39
41
|
s.rdoc_options = ["--charset=UTF-8"]
|
40
42
|
s.require_paths = ["lib"]
|
41
|
-
s.rubygems_version = %q{1.3.
|
43
|
+
s.rubygems_version = %q{1.3.6}
|
42
44
|
s.summary = %q{Your friendly neighborhood hash toolkit.}
|
43
45
|
s.test_files = [
|
44
|
-
"spec/hashie/
|
46
|
+
"spec/hashie/clash_spec.rb",
|
47
|
+
"spec/hashie/dash_spec.rb",
|
45
48
|
"spec/hashie/hash_spec.rb",
|
46
49
|
"spec/hashie/mash_spec.rb",
|
47
50
|
"spec/spec_helper.rb"
|
data/lib/hashie.rb
CHANGED
data/lib/hashie/clash.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'hashie/hash'
|
2
|
+
|
3
|
+
module Hashie
|
4
|
+
#
|
5
|
+
# A Clash is a "Chainable Lazy Hash". Inspired by libraries such as Arel,
|
6
|
+
# a Clash allows you to chain together method arguments to build a
|
7
|
+
# hash, something that's especially useful if you're doing something
|
8
|
+
# like constructing a complex options hash. Here's a basic example:
|
9
|
+
#
|
10
|
+
# c = Hashie::Clash.new.conditions(:foo => 'bar').order(:created_at)
|
11
|
+
# c # => {:conditions => {:foo => 'bar'}, :order => :created_at}
|
12
|
+
#
|
13
|
+
# Clash provides another way to create sub-hashes by using bang notation.
|
14
|
+
# You can dive into a sub-hash by providing a key with a bang and dive
|
15
|
+
# back out again with the _end! method. Example:
|
16
|
+
#
|
17
|
+
# c = Hashie::Clash.new.conditions!.foo('bar').baz(123)._end!.order(:created_at)
|
18
|
+
# c # => {:conditions => {:foo => 'bar', :baz => 123}, :order => :created_at}
|
19
|
+
#
|
20
|
+
# Because the primary functionality of Clash is to build options objects,
|
21
|
+
# all keys are converted to symbols since many libraries expect symbols explicitly
|
22
|
+
# for keys.
|
23
|
+
#
|
24
|
+
class Clash < ::Hash
|
25
|
+
class ChainError < ::StandardError; end
|
26
|
+
# The parent Clash if this Clash was created via chaining.
|
27
|
+
attr_reader :_parent
|
28
|
+
|
29
|
+
# Initialize a new clash by passing in a Hash to
|
30
|
+
# convert and, optionally, the parent to which this
|
31
|
+
# Clash is chained.
|
32
|
+
def initialize(other_hash = {}, parent = nil)
|
33
|
+
@_parent = parent
|
34
|
+
other_hash.each_pair do |k, v|
|
35
|
+
self[k.to_sym] = v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Jump back up a level if you are using bang method
|
40
|
+
# chaining. For example:
|
41
|
+
#
|
42
|
+
# c = Hashie::Clash.new.foo('bar')
|
43
|
+
# c.baz!.foo(123) # => c[:baz]
|
44
|
+
# c.baz!._end! # => c
|
45
|
+
def _end!
|
46
|
+
self._parent
|
47
|
+
end
|
48
|
+
|
49
|
+
def id(*args) #:nodoc:
|
50
|
+
method_missing(:id, *args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def merge_store(key, *args) #:nodoc:
|
54
|
+
case args.length
|
55
|
+
when 1
|
56
|
+
val = args.first
|
57
|
+
val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
|
58
|
+
else
|
59
|
+
val = args
|
60
|
+
end
|
61
|
+
|
62
|
+
self[key.to_sym] = val
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def method_missing(name, *args) #:nodoc:
|
67
|
+
name = name.to_s
|
68
|
+
if name.match(/!$/) && args.empty?
|
69
|
+
key = name[0...-1].to_sym
|
70
|
+
|
71
|
+
if self[key].nil?
|
72
|
+
self[key] = Clash.new({}, self)
|
73
|
+
elsif self[key].is_a?(::Hash) && !self[key].is_a?(Clash)
|
74
|
+
self[key] = Clash.new(self[key], self)
|
75
|
+
else
|
76
|
+
raise ChainError, "Tried to chain into a non-hash key."
|
77
|
+
end
|
78
|
+
|
79
|
+
self[key]
|
80
|
+
elsif args.any?
|
81
|
+
key = name.to_sym
|
82
|
+
self.merge_store(key, *args)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Hashie::Clash do
|
4
|
+
before do
|
5
|
+
@c = Hashie::Clash.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should be able to set an attribute via method_missing' do
|
9
|
+
@c.foo('bar')
|
10
|
+
@c[:foo].should == 'bar'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be able to set multiple attributes' do
|
14
|
+
@c.foo('bar').baz('wok')
|
15
|
+
@c.should == {:foo => 'bar', :baz => 'wok'}
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should convert multiple arguments into an array' do
|
19
|
+
@c.foo(1, 2, 3)
|
20
|
+
@c[:foo].should == [1,2,3]
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be able to use bang notation to create a new Clash on a key' do
|
24
|
+
@c.foo!
|
25
|
+
@c[:foo].should be_kind_of(Hashie::Clash)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should be able to chain onto the new Clash when using bang notation' do
|
29
|
+
@c.foo!.bar('abc').baz(123)
|
30
|
+
@c.should == {:foo => {:bar => 'abc', :baz => 123}}
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be able to jump back up to the parent in the chain with #_end!' do
|
34
|
+
@c.foo!.bar('abc')._end!.baz(123)
|
35
|
+
@c.should == {:foo => {:bar => 'abc'}, :baz => 123}
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should merge rather than replace existing keys' do
|
39
|
+
@c.where(:abc => 'def').where(:hgi => 123)
|
40
|
+
@c.should == {:where => {:abc => 'def', :hgi => 123}}
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Michael Bleigh
|
@@ -9,19 +14,21 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-05 00:00:00 -05:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: rspec
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
23
29
|
version: "0"
|
24
|
-
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
25
32
|
description: Hashie is a small collection of tools that make hashes more powerful. Currently includes Mash (Mocking Hash) and Dash (Discrete Hash).
|
26
33
|
email: michael@intridea.com
|
27
34
|
executables: []
|
@@ -40,10 +47,12 @@ files:
|
|
40
47
|
- VERSION
|
41
48
|
- hashie.gemspec
|
42
49
|
- lib/hashie.rb
|
50
|
+
- lib/hashie/clash.rb
|
43
51
|
- lib/hashie/dash.rb
|
44
52
|
- lib/hashie/hash.rb
|
45
53
|
- lib/hashie/hash_extensions.rb
|
46
54
|
- lib/hashie/mash.rb
|
55
|
+
- spec/hashie/clash_spec.rb
|
47
56
|
- spec/hashie/dash_spec.rb
|
48
57
|
- spec/hashie/hash_spec.rb
|
49
58
|
- spec/hashie/mash_spec.rb
|
@@ -62,22 +71,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
62
71
|
requirements:
|
63
72
|
- - ">="
|
64
73
|
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
65
76
|
version: "0"
|
66
|
-
version:
|
67
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
78
|
requirements:
|
69
79
|
- - ">="
|
70
80
|
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
71
83
|
version: "0"
|
72
|
-
version:
|
73
84
|
requirements: []
|
74
85
|
|
75
86
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.3.
|
87
|
+
rubygems_version: 1.3.6
|
77
88
|
signing_key:
|
78
89
|
specification_version: 3
|
79
90
|
summary: Your friendly neighborhood hash toolkit.
|
80
91
|
test_files:
|
92
|
+
- spec/hashie/clash_spec.rb
|
81
93
|
- spec/hashie/dash_spec.rb
|
82
94
|
- spec/hashie/hash_spec.rb
|
83
95
|
- spec/hashie/mash_spec.rb
|