key_struct 0.1.2 → 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.
@@ -74,13 +74,33 @@ The struct initializer checks for invalid arguments:
74
74
 
75
75
  name = Name.new(:this_is_a_typo => "Xavier") # --> raises ArgumentError
76
76
 
77
- == Equaltiy
77
+ == Comparison
78
78
 
79
79
  KeyStruct classes define the == operator, which returns true iff all corresponding struct members are equal (likewise via ==)
80
80
 
81
81
  Name.new(:first => "John", :last => "Doe") == Name.new(:first => "John", :last => "Doe") # --> true
82
82
  Name.new(:first => "John", :last => "Doe") == Name.new(:first => "Jane", :last => "Doe") # --> false
83
83
 
84
+ As a convenience when a well-defined ordering is needed, KeyStruct classes
85
+ defines the <=> operator and includes the +Comparable+ module. The <=>
86
+ operator applies <=> to the coresponding struct members sequentially,
87
+ returning the first that is non-0. The comparison is performed in the order
88
+ the keys were listed in the class definition, so the first key is the
89
+ primary comparison key, and so on down the line. Thus:
90
+
91
+ Name = KeyStruct[:first, :last]
92
+ Name.new(:first => "Abigail", :last => "Zither") <=> Name.new(:first => "Zenobia", :last => "Aardvark") # --> -1
93
+
94
+ LastFirst = KeyStruct[:last, :first]
95
+ LastFirst.new(:first => "Abigail", :last => "Zither") <=> LastFirst.new(:first => "Zenobia", :last => "Aardvark") # --> +1
96
+
97
+ == Converting to a hash
98
+
99
+ KeyStruct classes define a +to_hash+ method that returns a hash containing
100
+ all members and their values:
101
+
102
+ Name.new(:first => "Jack", :last => "Ripper").to_hash # --> {:first => "Jack", :last => "Ripper")
103
+
84
104
  == Installation
85
105
 
86
106
  Install via:
@@ -97,6 +117,12 @@ Requires ruby >= 1.9.2. (Has been tested on MRI 1.9.2 and MRI 1.9.3)
97
117
 
98
118
  == History
99
119
 
120
+ Release Notes:
121
+
122
+ * 0.2.0 - Introduced <=> and to_hash
123
+ * 0.1.0 - Introduced ==
124
+ * 0.0.1 - Initial version
125
+
100
126
  Past: There was some discussion around this idea in this thread:
101
127
  http://www.ruby-forum.com/topic/138124 in 2008.
102
128
 
@@ -1,38 +1,2 @@
1
1
  require "key_struct/version"
2
-
3
- module KeyStruct
4
-
5
- def self.reader(*keys)
6
- define_key_struct(:attr_reader, keys)
7
- end
8
-
9
- def self.accessor(*keys)
10
- define_key_struct(:attr_accessor, keys)
11
- end
12
-
13
- instance_eval do
14
- alias :[] :accessor
15
- end
16
-
17
- private
18
-
19
- def self.define_key_struct(access, keys)
20
- Class.new.class_eval do
21
- keyvalues = Hash[*keys.map{|key| (Hash === key) ? key.to_a : [key, nil]}.flatten(2)]
22
- keys = keyvalues.keys
23
- send access, *keys
24
- define_method(:initialize) do |args={}|
25
- args = keyvalues.merge(args)
26
- keys.each do |key|
27
- instance_variable_set("@#{key}".to_sym, args.delete(key))
28
- end
29
- raise ArgumentError, "Invalid argument(s): #{args.keys.map(&:inspect).join(' ')}; KeyStruct accepts #{keys.map(&:inspect).join(' ')}" if args.any?
30
- end
31
- define_method(:==) do |other|
32
- keys.all?{|key| self.send(key) == other.send(key)}
33
- end
34
- self
35
- end
36
- end
37
-
38
- end
2
+ require "key_struct/key_struct"
@@ -0,0 +1,48 @@
1
+ module KeyStruct
2
+
3
+ def self.reader(*keys)
4
+ define_key_struct(:attr_reader, keys)
5
+ end
6
+
7
+ def self.accessor(*keys)
8
+ define_key_struct(:attr_accessor, keys)
9
+ end
10
+
11
+ instance_eval do
12
+ alias :[] :accessor
13
+ end
14
+
15
+ private
16
+
17
+ def self.define_key_struct(access, keys)
18
+ Class.new.class_eval do
19
+ include Comparable
20
+ keyvalues = Hash[*keys.map{|key| (Hash === key) ? key.to_a : [key, nil]}.flatten(2)]
21
+ keys = keyvalues.keys
22
+ send access, *keys
23
+ define_method(:initialize) do |args={}|
24
+ args = keyvalues.merge(args)
25
+ keys.each do |key|
26
+ instance_variable_set("@#{key}".to_sym, args.delete(key))
27
+ end
28
+ raise ArgumentError, "Invalid argument(s): #{args.keys.map(&:inspect).join(' ')}; KeyStruct accepts #{keys.map(&:inspect).join(' ')}" if args.any?
29
+ end
30
+ define_method(:==) do |other|
31
+ keys.all?{|key| self.send(key) == other.send(key)}
32
+ end
33
+ define_method(:<=>) do |other|
34
+ keys.each do |key|
35
+ cmp = (self.send(key) <=> other.send(key))
36
+ return cmp unless cmp == 0
37
+ end
38
+ 0
39
+ end
40
+ define_method(:to_hash) do
41
+ Hash[*keys.map{ |key| [key, self.send(key)]}.flatten(2)]
42
+ end
43
+ self
44
+ end
45
+ end
46
+
47
+ end
48
+
@@ -1,3 +1,3 @@
1
1
  module KeyStruct
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -113,15 +113,36 @@ describe "KeyStruct" do
113
113
  end
114
114
  end
115
115
 
116
- context "==" do
116
+ context "comparison" do
117
117
  before(:all) do
118
- @klass = KeyStruct.accessor(:a, :b)
118
+ @klass = KeyStruct.accessor(:a, :b, :c)
119
119
  end
120
120
 
121
121
  it "returns true iff all members are ==" do
122
122
  @klass.new(:a => 1, :b => 2).should == @klass.new(:a => 1, :b => 2)
123
123
  @klass.new(:a => 1, :b => 2).should_not == @klass.new(:a => 1, :b => 3)
124
124
  end
125
+
126
+ it "compares based on primary key" do
127
+ @klass.new(:a => 1, :b => 2).should < @klass.new(:a => 2, :b => 2)
128
+ end
129
+
130
+ it "compares based on second key if first is equal" do
131
+ @klass.new(:a => 1, :b => 2).should > @klass.new(:a => 1, :b => 1)
132
+ end
133
+
134
+ it "compares based on third key if first two are equal" do
135
+ @klass.new(:a => 1, :b => 2, :c => 3).should > @klass.new(:a => 1, :b => 2, :c => 1)
136
+ end
137
+
138
+ it "returns zero for <=> if all are equal" do
139
+ (@klass.new(:a => 1, :b => 2) <=> @klass.new(:a => 1, :b => 2)).should == 0
140
+ end
141
+
142
+ end
143
+
144
+ it "returns hash using to_hash" do
145
+ KeyStruct.accessor(:a => 3, :b => 4).new.to_hash.should == {:a => 3, :b => 4}
125
146
  end
126
147
 
127
148
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: key_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-29 00:00:00.000000000 Z
12
+ date: 2011-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70161596448140 !ruby/object:Gem::Requirement
16
+ requirement: &70350516522720 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70161596448140
24
+ version_requirements: *70350516522720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: simplecov
27
- requirement: &70161596447560 !ruby/object:Gem::Requirement
27
+ requirement: &70350516521800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70161596447560
35
+ version_requirements: *70350516521800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: simplecov-gem-adapter
38
- requirement: &70161596438560 !ruby/object:Gem::Requirement
38
+ requirement: &70350516536920 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70161596438560
46
+ version_requirements: *70350516536920
47
47
  description: Defines KeyStruct analogous to Struct, but constructor takes keyword
48
48
  arguments
49
49
  email:
@@ -61,6 +61,7 @@ files:
61
61
  - Rakefile
62
62
  - key_struct.gemspec
63
63
  - lib/key_struct.rb
64
+ - lib/key_struct/key_struct.rb
64
65
  - lib/key_struct/version.rb
65
66
  - spec/key_struct_spec.rb
66
67
  - spec/spec_helper.rb