hamsterdam 1.0.1 → 1.0.2

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/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ Hamsterdam v1.0.2
2
+ * Field name defs, constructor keys and merge keys are now stringified internally to prevent string/symbol mismatching
3
+ * Added syntax helper for this kind of thing: class Castle < Hamsterdam::Struct(:gate, :walls)
4
+
1
5
  Hamsterdam v1.0.1
2
6
  * Added nice to_s and inspect
3
7
  * Also storing .field_names_list as another way of getting field names of a struct, but retaining order of declaration (.field_names is a Hamster.set, .field_names_list is a Hamster.list)
data/TODO.txt ADDED
@@ -0,0 +1,4 @@
1
+ - Add commas in to_s
2
+ - .set_defaults({}) to provide default values for constructors
3
+ - Want to use fun "Status < Hamsterdam::Struct(:one, :two)" but something is wrong with inheritance of field_names that blows up the flesh_out func.
4
+ - FIXED: Symbol/string insensitivity (use symbols internally and when listing field names, but accept :foo and 'foo' when constructing and merging
data/lib/hamsterdam.rb CHANGED
@@ -1,11 +1,16 @@
1
1
  require 'hamster'
2
2
 
3
3
  module Hamsterdam
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.2"
5
+
6
+ def self.Struct(*field_names)
7
+ Hamsterdam::Struct.define(*field_names)
8
+ end
5
9
 
6
10
  class Struct
7
11
  def self.define(*field_names)
8
12
  struct_class = Class.new(Hamsterdam::Struct) do
13
+ field_names = field_names.map &:to_sym
9
14
  field_names.each do |fname|
10
15
  define_method fname do
11
16
  return @data[fname]
@@ -22,10 +27,18 @@ module Hamsterdam
22
27
  struct_class.instance_variable_set(:@field_names_list, Hamster.list(*field_names))
23
28
  class << struct_class
24
29
  def field_names
25
- @field_names
30
+ if !@field_names.nil?
31
+ @field_names
32
+ else
33
+ superclass.field_names
34
+ end
26
35
  end
27
36
  def field_names_list
28
- @field_names_list
37
+ if !@field_names_list.nil?
38
+ @field_names_list
39
+ else
40
+ superclass.field_names_list
41
+ end
29
42
  end
30
43
  end
31
44
  struct_class
@@ -88,7 +101,9 @@ module Hamsterdam
88
101
  end
89
102
 
90
103
  def flesh_out(data)
104
+ # binding.pry
91
105
  fnames = self.class.field_names
106
+ data = symbolize_keys(data)
92
107
  miss = fnames - data.keys
93
108
  if miss.any?
94
109
  return miss.inject(data) { |h,name| h.put(name,nil) }
@@ -97,5 +112,14 @@ module Hamsterdam
97
112
  end
98
113
  end
99
114
 
115
+ def symbolize_keys(data)
116
+ data.reduce(data) do |memo,k,v|
117
+ if Symbol === k
118
+ memo
119
+ else
120
+ memo.delete(k).put(k.to_sym, v)
121
+ end
122
+ end
123
+ end
100
124
  end
101
125
  end
@@ -47,6 +47,22 @@ describe "Hamsterdam structures" do
47
47
  it "raises helpful error when constructed with invalid objects" do
48
48
  lambda do struct_class.new("LAWDY") end.should raise_error /Do not want.*LAWDY/
49
49
  end
50
+
51
+ describe "inheritance-based definition" do
52
+ class Castle < Hamsterdam::Struct(:gate, :mote, :walls)
53
+ def tally
54
+ gate + mote + walls
55
+ end
56
+ end
57
+
58
+ it "provides convenient syntax for deriving classes from immutable struct def" do
59
+ c = Castle.new gate: 2, mote: 1, walls: 4
60
+ c.gate.should == 2
61
+ c.mote.should == 1
62
+ c.walls.should == 4
63
+ c.tally.should == 7
64
+ end
65
+ end
50
66
  end
51
67
 
52
68
  describe "equality" do
@@ -157,10 +173,39 @@ describe "Hamsterdam structures" do
157
173
  end
158
174
 
159
175
  it "does a nice job with Hamster Lists, Sets, and Hashes" do
160
- thinger = Hamstest::Thinger.new a_hash: Hamster.hash(red: "fish"), a_set: Hamster.set(42,37), a_list: Hamster.list(:oh, :the, :things)
161
- expected = "<Thinger a_hash: {:red => \"fish\"} a_set: {42, 37} a_list: [:oh, :the, :things]>"
176
+ thinger = Hamstest::Thinger.new a_hash: Hamster.hash(red: "fish"), a_set: Hamster.set(42), a_list: Hamster.list(:oh, :the, :things)
177
+ expected = "<Thinger a_hash: {:red => \"fish\"} a_set: {42} a_list: [:oh, :the, :things]>"
162
178
  thinger.inspect.should == expected
163
179
  thinger.to_s.should == expected
164
180
  end
165
181
  end
182
+
183
+ describe "symbol/string insensitivity" do
184
+ let(:mixed_up) { Hamsterdam::Struct.define(:foo, 'bar') }
185
+
186
+ it "lets you define the field names using a mix of string and symbols" do
187
+ val = mixed_up.new(foo: 1, bar: 2)
188
+ val.foo.should == 1
189
+ val.bar.should == 2
190
+ val = val.set_foo(3)
191
+ val.foo.should == 3
192
+ end
193
+
194
+ it "lets you construct new values using a mix of strings and symbols" do
195
+ val = mixed_up.new("foo" => 1, :bar => 2)
196
+ val.foo.should == 1
197
+ val.bar.should == 2
198
+ end
199
+
200
+ it "lets you merge values using a mix of strings and symbols" do
201
+ val = mixed_up.new("foo" => 1, :bar => 2)
202
+ val.foo.should == 1
203
+ val.bar.should == 2
204
+ val = val.merge(:foo => 3, "bar" => 4)
205
+ val.foo.should == 3
206
+ val.bar.should == 4
207
+
208
+ val.to_hamster_hash.should == Hamster.hash(foo: 3, bar: 4)
209
+ end
210
+ end
166
211
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hamsterdam
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -102,6 +102,7 @@ files:
102
102
  - Gemfile
103
103
  - README.md
104
104
  - Rakefile
105
+ - TODO.txt
105
106
  - hamsterdam.gemspec
106
107
  - lib/hamsterdam.rb
107
108
  - rake_tasks/rspec.rake