hamster 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.1.12 / 2009-12-10
2
+
3
+ * List methods are now lazy where feasible
4
+
5
+ * Now works under Ruby >= 1.8.6
6
+
1
7
  === 0.1.8 / 2009-11-29
2
8
 
3
9
  * Add convenience constructors: List[], Set[], and Hash[]
data/README.rdoc CHANGED
@@ -41,6 +41,8 @@ The same goes for <tt>#remove</tt>:
41
41
 
42
42
  As mentioned earlier, persistent data structures perform a copy whenever they are modified meaning there is never any chance that two threads could be modifying the same instance at any one time. And, because they are very efficient copies, you don't need to worry about using up gobs of heap space in the process.
43
43
 
44
+ Moreover, because they're immutable, you can pass them around between objects, methods, and functions and never worry about data corruption; no more defensive calls to <tt>collection.dup</tt>!
45
+
44
46
  == OK, that sounds mildly interesting. What's the downside--there's always a downside?
45
47
 
46
48
  There's a potential performance hit when compared with MRI's built-in, native, hand-crafted C-code implementation of <tt>Hash</tt>. For example:
@@ -89,7 +91,7 @@ The <tt>Hamster::Hash</tt> version on the other hand was unchanged from the orig
89
91
 
90
92
  Well, I could show you one but I'd have to re-write--or at least wrap--most <tt>Hash</tt> methods to make it generic, or at least write some application-specific code that synchronised using a <tt>Mutex</tt> and ... well ... it's hard, I always make mistakes, I always end up with weird edge cases and race conditions so, I'll leave that as an exercise for you :)
91
93
 
92
- And that, my friends, is why you might want to use one :)
94
+ And don't forget that even if threading isn't a concern for you, the safety provided by immutability is worth it.
93
95
 
94
96
  == So, you mentioned Sets, Lists, and Stacks?
95
97
 
@@ -97,20 +99,49 @@ Indeed I did.
97
99
 
98
100
  === Lists
99
101
 
100
- list = Hamster.list(1, 2, 3)
102
+ Lists have a head--the value of the item at the head of the list--and a tail--containing the remaining items. For example:
103
+
104
+ list = Hamster.list(1, 2, 3)
105
+
106
+ list.head # => 1
107
+ list.tail # => Hamster.list(2, 3)
108
+
109
+ To add to a list you use <tt>#cons</tt>:
110
+
111
+ original = Hamster.list(1, 2, 3)
112
+ copy = original.cons(0) # => Hamster.list(0, 1, 2, 3)
113
+
114
+ Notice how modifying a list actually returns a new list. That's because Hamster lists are immutable. Thankfully, just like Hamster <tt>Set</tt> and <tt>Hash</tt>, they're also very efficient at making copies!
115
+
116
+ Lists are, where possible, lazy. That is, they try to defer processing items until absolutely necessary. For example, given a crude function to detect prime numbers:
117
+
118
+ def prime?(n)
119
+ 2.upto(Math.sqrt(n).round) { |i| return false if n % i == 0 }
120
+ true
121
+ end
101
122
 
102
- list.head # => 1
103
- list.tail # => Hamster.list(2, 3)
123
+ The following code will only call <tt>#prime?</tt> as many times as necessary to generate the first 3 prime numbers between 10000 and 1000000:
104
124
 
105
- def prime?(n)
106
- 2.upto(Math.sqrt(n).round) { |i| return false if n % i == 0 }
107
- true
108
- end
125
+ Hamster.interval(10000, 1000000).filter { |i| prime?(i) }.take(3) # => 0.0009s
109
126
 
110
- Hamster.interval(10000, 1000000).filter { |i| prime?(i) }.take(3)
127
+ Compare that to the conventional equivalent which needs to calculate all possible values in the range before taking the first 3:
128
+
129
+ (10000..1000000).select { |i| prime?(i) }[1, 3] # => 10s
130
+
131
+ Besides <tt>Hamster.list</tt> there is <tt>Hamster.interval(from, to)</tt> and <tt>Hamster.stream { a_block }</tt>.
132
+
133
+ <tt>.interval</tt> (aliased as <tt>.range</tt>) creates a lazy list equivalent to a list containing all the values between <tt>from</tt> and <tt>to</tt> without actually creating a list that big.
134
+
135
+ <tt>.stream</tt> allows you to creates infinite lists. Each time a new value is required, the supplied block is called.
111
136
 
112
137
  === Stacks
113
138
 
114
139
  === Sets
115
140
 
116
- === Hash
141
+ == Disclaimer
142
+
143
+ Hamster started out as a spike to prove a point and has since morphed into something I actually use. My primary concern has been to round out the functionality with good test coverage and clean, readable code.
144
+
145
+ Performance is pretty good--especially with lazy lists--but there are some things which need to be converted from recursive to iterative due to a lack of Tail-Call-Optimisation in Ruby. It's on the list ;-)
146
+
147
+ Documentation is sparse but I've tried as best I can to write specs that reads as documentation. I've also tried to alias methods as their <tt>Enumerable</tt> equivalents where possible to make it easier for people to migrate code.
data/lib/hamster/hash.rb CHANGED
@@ -3,7 +3,7 @@ require 'hamster/trie'
3
3
  module Hamster
4
4
 
5
5
  def self.hash(pairs = {})
6
- pairs.reduce(Hash.new) { |hash, pair| hash.put(pair.first, pair.last) }
6
+ pairs.inject(Hash.new) { |hash, pair| hash.put(pair.first, pair.last) }
7
7
  end
8
8
 
9
9
  class Hash
@@ -51,13 +51,13 @@ module Hamster
51
51
  end
52
52
 
53
53
  def each
54
- block_given? or return enum_for(__method__)
54
+ block_given? or return self
55
55
  @trie.each { |entry| yield(entry.key, entry.value) }
56
56
  self
57
57
  end
58
58
 
59
59
  def map
60
- block_given? or return enum_for(:each)
60
+ block_given? or return self
61
61
  if empty?
62
62
  self
63
63
  else
@@ -73,7 +73,7 @@ module Hamster
73
73
  alias_method :inject, :reduce
74
74
 
75
75
  def filter
76
- block_given? or return enum_for(__method__)
76
+ block_given? or return self
77
77
  trie = @trie.filter { |entry| yield(entry.key, entry.value) }
78
78
  if !trie.equal?(@trie)
79
79
  self.class.new(trie)
@@ -84,7 +84,7 @@ module Hamster
84
84
  alias_method :select, :filter
85
85
 
86
86
  def reject
87
- block_given? or return enum_for(__method__)
87
+ block_given? or return self
88
88
  select { |key, value| !yield(key, value) }
89
89
  end
90
90
 
@@ -96,6 +96,8 @@ module Hamster
96
96
  end
97
97
  false
98
98
  end
99
+ alias_method :exist?, :any?
100
+ alias_method :exists?, :any?
99
101
 
100
102
  def all?
101
103
  if block_given?
data/lib/hamster/list.rb CHANGED
@@ -3,7 +3,12 @@ module Hamster
3
3
  class << self
4
4
 
5
5
  def list(*items)
6
- items.reverse.reduce(EmptyList) { |list, item| list.cons(item) }
6
+ items.reverse.inject(EmptyList) { |list, item| list.cons(item) }
7
+ end
8
+
9
+ def stream(&block)
10
+ block_given? or return EmptyList
11
+ Stream.new(yield) { stream(&block) }
7
12
  end
8
13
 
9
14
  def interval(from, to)
@@ -43,6 +48,7 @@ module Hamster
43
48
  block_given? or return self
44
49
  Stream.new(yield(head)) { tail.map(&block) }
45
50
  end
51
+ alias_method :collect, :map
46
52
 
47
53
  def reduce(memo, &block)
48
54
  block_given? or return memo
@@ -120,6 +126,14 @@ module Hamster
120
126
  end
121
127
  alias_method :clone, :dup
122
128
 
129
+ def to_a
130
+ reduce([]) { |ary, item| ary << item }
131
+ end
132
+
133
+ def inspect
134
+ to_a.inspect
135
+ end
136
+
123
137
  private
124
138
 
125
139
  def method_missing(name, *args, &block)
@@ -135,7 +149,7 @@ module Hamster
135
149
  # identify the series of car and cdr operations that is performed by the function. The order in which the 'a's and
136
150
  # 'd's appear is the inverse of the order in which the corresponding operations are performed.
137
151
  def accessor(sequence)
138
- sequence.split(//).reverse!.reduce(self) do |memo, char|
152
+ sequence.split(//).reverse!.inject(self) do |memo, char|
139
153
  case char
140
154
  when "a" then memo.head
141
155
  when "d" then memo.tail
@@ -206,6 +220,7 @@ module Hamster
206
220
  def map
207
221
  self
208
222
  end
223
+ alias_method :collect, :map
209
224
 
210
225
  def reduce(memo)
211
226
  memo
data/lib/hamster/set.rb CHANGED
@@ -3,7 +3,7 @@ require 'hamster/trie'
3
3
  module Hamster
4
4
 
5
5
  def self.set(*items)
6
- items.reduce(Set.new) { |set, item| set.add(item) }
6
+ items.inject(Set.new) { |set, item| set.add(item) }
7
7
  end
8
8
 
9
9
  class Set
@@ -45,13 +45,13 @@ module Hamster
45
45
  end
46
46
 
47
47
  def each
48
- block_given? or return enum_for(__method__)
48
+ block_given? or return self
49
49
  @trie.each { |entry| yield(entry.key) }
50
50
  self
51
51
  end
52
52
 
53
53
  def map
54
- block_given? or return enum_for(:each)
54
+ block_given? or return self
55
55
  if empty?
56
56
  self
57
57
  else
@@ -67,7 +67,7 @@ module Hamster
67
67
  alias_method :inject, :reduce
68
68
 
69
69
  def filter
70
- block_given? or return enum_for(__method__)
70
+ block_given? or return self
71
71
  trie = @trie.filter { |entry| yield(entry.key) }
72
72
  if !trie.equal?(@trie)
73
73
  self.class.new(trie)
@@ -78,7 +78,7 @@ module Hamster
78
78
  alias_method :select, :filter
79
79
 
80
80
  def reject
81
- block_given? or return enum_for(__method__)
81
+ block_given? or return self
82
82
  select { |item| !yield(item) }
83
83
  end
84
84
 
@@ -90,6 +90,8 @@ module Hamster
90
90
  end
91
91
  false
92
92
  end
93
+ alias_method :exist?, :any?
94
+ alias_method :exists?, :any?
93
95
 
94
96
  def all?
95
97
  if block_given?
data/lib/hamster/stack.rb CHANGED
@@ -3,12 +3,12 @@ require 'hamster/list'
3
3
  module Hamster
4
4
 
5
5
  def self.stack
6
- Stack.new
6
+ EmptyStack
7
7
  end
8
8
 
9
9
  class Stack
10
10
 
11
- def initialize(list = Hamster.list)
11
+ def initialize(list)
12
12
  @list = list
13
13
  end
14
14
 
@@ -19,6 +19,7 @@ module Hamster
19
19
  def size
20
20
  @list.size
21
21
  end
22
+ alias_method :length, :size
22
23
 
23
24
  def top
24
25
  @list.head
@@ -30,15 +31,17 @@ module Hamster
30
31
 
31
32
  def pop
32
33
  list = @list.tail
33
- if !list.equal?(@list)
34
- self.class.new(list)
34
+ if list.empty?
35
+ EmptyStack
35
36
  else
36
- self
37
+ self.class.new(list)
37
38
  end
38
39
  end
39
40
 
40
41
  def eql?(other)
41
- other.is_a?(self.class) && @list.eql?(other.instance_eval{@list})
42
+ return true if other.equal?(self)
43
+ return false unless other.class.equal?(self.class)
44
+ @list.eql?(other.instance_eval{@list})
42
45
  end
43
46
  alias_method :==, :eql?
44
47
 
@@ -49,4 +52,6 @@ module Hamster
49
52
 
50
53
  end
51
54
 
55
+ EmptyStack = Stack.new(Hamster.list)
56
+
52
57
  end
@@ -1,5 +1,5 @@
1
1
  module Hamster
2
2
 
3
- VERSION = "0.1.11".freeze
3
+ VERSION = "0.1.12".freeze
4
4
 
5
5
  end
@@ -2,55 +2,59 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Hamster::Hash do
4
4
 
5
- describe "#any?" do
5
+ [:any?, :exist?, :exists?].each do |method|
6
6
 
7
- describe "when empty" do
7
+ describe "##{method}" do
8
8
 
9
- before do
10
- @hash = Hamster.hash
11
- end
9
+ describe "when empty" do
12
10
 
13
- it "with a block returns false" do
14
- @hash.any? {}.should be_false
15
- end
11
+ before do
12
+ @hash = Hamster.hash
13
+ end
14
+
15
+ it "with a block returns false" do
16
+ @hash.send(method) {}.should be_false
17
+ end
18
+
19
+ it "with no block returns false" do
20
+ @hash.send(method).should be_false
21
+ end
16
22
 
17
- it "with no block returns false" do
18
- @hash.any?.should be_false
19
23
  end
20
24
 
21
- end
25
+ describe "when not empty" do
22
26
 
23
- describe "when not empty" do
27
+ before do
28
+ @hash = Hamster.hash("A" => "aye", "B" => "bee", "C" => "see", nil => "NIL")
29
+ end
24
30
 
25
- before do
26
- @hash = Hamster.hash("A" => "aye", "B" => "bee", "C" => "see", nil => "NIL")
27
- end
31
+ describe "with a block" do
28
32
 
29
- describe "with a block" do
33
+ [
34
+ ["A", "aye"],
35
+ ["B", "bee"],
36
+ ["C", "see"],
37
+ [nil, "NIL"],
38
+ ].each do |pair|
30
39
 
31
- [
32
- ["A", "aye"],
33
- ["B", "bee"],
34
- ["C", "see"],
35
- [nil, "NIL"],
36
- ].each do |pair|
40
+ it "returns true if the block ever returns true (#{pair.inspect})" do
41
+ @hash.send(method) { |key, value| key == pair.first && value == pair.last }.should be_true
42
+ end
37
43
 
38
- it "returns true if the block ever returns true (#{pair.inspect})" do
39
- @hash.any? { |key, value| key == pair.first && value == pair.last }.should be_true
40
- end
44
+ it "returns false if the block always returns false" do
45
+ @hash.send(method) { |key, value| key == "D" && value == "dee" }.should be_false
46
+ end
41
47
 
42
- it "returns false if the block always returns false" do
43
- @hash.any? { |key, value| key == "D" && value == "dee" }.should be_false
44
48
  end
45
49
 
46
50
  end
47
51
 
48
- end
52
+ describe "with no block" do
49
53
 
50
- describe "with no block" do
54
+ it "returns true" do
55
+ @hash.send(method).should be_true
56
+ end
51
57
 
52
- it "returns true" do
53
- @hash.any?.should be_true
54
58
  end
55
59
 
56
60
  end
@@ -22,10 +22,10 @@ describe Hamster::Hash do
22
22
 
23
23
  end
24
24
 
25
- describe "with no block (external iteration)" do
25
+ describe "with no block" do
26
26
 
27
- it "returns an enumerator over all key/value pairs" do
28
- Hash[*@hash.each.to_a.flatten].should == {"A" => "aye", "B" => "bee", "C" => "see"}
27
+ it "returns self" do
28
+ @hash.each.should equal(@hash)
29
29
  end
30
30
 
31
31
  end
@@ -43,11 +43,11 @@ describe Hamster::Hash do
43
43
  describe "with no block" do
44
44
 
45
45
  before do
46
- @enumerator = @original.send(method)
46
+ @result = @original.send(method)
47
47
  end
48
48
 
49
- it "returns an enumerator over the values" do
50
- Hamster.hash(@enumerator.to_a).should == Hamster.hash("A" => "aye", "B" => "bee", "C" => "see")
49
+ it "returns self" do
50
+ @result.should equal(@original)
51
51
  end
52
52
 
53
53
  end
@@ -44,15 +44,11 @@ describe Hamster::Hash do
44
44
  describe "with no block" do
45
45
 
46
46
  before do
47
- @enumerator = @original.send(method)
47
+ @result = @original.send(method)
48
48
  end
49
49
 
50
- it "preserves the original values" do
51
- @original.should == Hamster.hash("A" => "aye", "B" => "bee", "C" => "see")
52
- end
53
-
54
- it "returns an enumerator over the key value pairs" do
55
- Hamster.hash(@enumerator.to_a).should == @original
50
+ it "returns self" do
51
+ @result.should equal(@original)
56
52
  end
57
53
 
58
54
  end
@@ -41,11 +41,11 @@ describe Hamster::Hash do
41
41
  describe "with no block" do
42
42
 
43
43
  before do
44
- @enumerator = @original.reject
44
+ @result = @original.reject
45
45
  end
46
46
 
47
- it "returns an enumerator over the values" do
48
- Hamster.hash(@enumerator.to_a).should == Hamster.hash("A" => "aye", "B" => "bee", "C" => "see")
47
+ it "returns self" do
48
+ @result.should equal(@original)
49
49
  end
50
50
 
51
51
  end
@@ -38,6 +38,35 @@ describe Hamster do
38
38
 
39
39
  end
40
40
 
41
+ describe ".stream" do
42
+
43
+ describe "with no block" do
44
+
45
+ before do
46
+ @stream = Hamster.stream
47
+ end
48
+
49
+ it "returns an empty list" do
50
+ @stream.should == Hamster.list
51
+ end
52
+
53
+ end
54
+
55
+ describe "with a block" do
56
+
57
+ before do
58
+ count = 0
59
+ @stream = Hamster.stream { count += 1 }
60
+ end
61
+
62
+ it "repeatedly calls the block" do
63
+ @stream.take(5).should == Hamster.list(1, 2, 3, 4, 5)
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
41
70
  [:interval, :range].each do |method|
42
71
 
43
72
  describe ".#{method}" do
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Hamster::List do
4
+
5
+ describe "#inspect" do
6
+
7
+ [
8
+ [],
9
+ ["A"],
10
+ ["A", "B", "C"],
11
+ ].each do |values|
12
+
13
+ describe "on #{values.inspect}" do
14
+
15
+ list = Hamster.list(*values)
16
+
17
+ it "returns #{values.inspect}" do
18
+ list.inspect.should == values.inspect
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -2,36 +2,40 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Hamster::List do
4
4
 
5
- describe "#map" do
5
+ [:map, :collect].each do |method|
6
6
 
7
- [
8
- [[], []],
9
- [["A"], ["a"]],
10
- [["A", "B", "C"], ["a", "b", "c"]],
11
- ].each do |values, result|
7
+ describe "##{method}" do
12
8
 
13
- describe "on #{values.inspect}" do
9
+ [
10
+ [[], []],
11
+ [["A"], ["a"]],
12
+ [["A", "B", "C"], ["a", "b", "c"]],
13
+ ].each do |values, result|
14
14
 
15
- list = Hamster.list(*values)
15
+ describe "on #{values.inspect}" do
16
16
 
17
- describe "with a block" do
17
+ list = Hamster.list(*values)
18
18
 
19
- it "returns #{result}" do
20
- list.map { |item| item.downcase }.should == Hamster.list(*result)
21
- end
19
+ describe "with a block" do
20
+
21
+ it "returns #{result}" do
22
+ list.send(method) { |item| item.downcase }.should == Hamster.list(*result)
23
+ end
24
+
25
+ it "is lazy" do
26
+ count = 0
27
+ list.send(method) { |item| count += 1 }
28
+ count.should <= 1
29
+ end
22
30
 
23
- it "is lazy" do
24
- count = 0
25
- list.map { |item| count += 1 }
26
- count.should <= 1
27
31
  end
28
32
 
29
- end
33
+ describe "without a block" do
30
34
 
31
- describe "without a block" do
35
+ it "returns self" do
36
+ list.send(method).should == list
37
+ end
32
38
 
33
- it "returns self" do
34
- list.map.should == list
35
39
  end
36
40
 
37
41
  end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Hamster::List do
4
+
5
+ describe "#to_a" do
6
+
7
+ [
8
+ [],
9
+ ["A"],
10
+ ["A", "B", "C"],
11
+ ].each do |values|
12
+
13
+ describe "on #{values.inspect}" do
14
+
15
+ list = Hamster.list(*values)
16
+
17
+ it "returns #{values.inspect}" do
18
+ list.to_a.should == values
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -2,54 +2,58 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Hamster::Set do
4
4
 
5
- describe "#any?" do
5
+ [:any?, :exist?, :exists?].each do |method|
6
6
 
7
- describe "when empty" do
7
+ describe "##{method}" do
8
8
 
9
- before do
10
- @set = Hamster.set
11
- end
9
+ describe "when empty" do
12
10
 
13
- it "with a block returns false" do
14
- @set.any? {}.should be_false
15
- end
11
+ before do
12
+ @set = Hamster.set
13
+ end
14
+
15
+ it "with a block returns false" do
16
+ @set.send(method) {}.should be_false
17
+ end
18
+
19
+ it "with no block returns false" do
20
+ @set.send(method).should be_false
21
+ end
16
22
 
17
- it "with no block returns false" do
18
- @set.any?.should be_false
19
23
  end
20
24
 
21
- end
25
+ describe "when not empty" do
22
26
 
23
- describe "when not empty" do
27
+ describe "with a block" do
24
28
 
25
- describe "with a block" do
29
+ before do
30
+ @set = Hamster.set("A", "B", "C", nil)
31
+ end
26
32
 
27
- before do
28
- @set = Hamster.set("A", "B", "C", nil)
29
- end
33
+ ["A", "B", "C", nil].each do |value|
30
34
 
31
- ["A", "B", "C", nil].each do |value|
35
+ it "returns true if the block ever returns true (#{value.inspect})" do
36
+ @set.send(method) { |item| item == value }.should be_true
37
+ end
32
38
 
33
- it "returns true if the block ever returns true (#{value.inspect})" do
34
- @set.any? { |item| item == value }.should be_true
35
39
  end
36
40
 
37
- end
41
+ it "returns false if the block always returns false" do
42
+ @set.send(method) { |item| item == "D" }.should be_false
43
+ end
38
44
 
39
- it "returns false if the block always returns false" do
40
- @set.any? { |item| item == "D" }.should be_false
41
45
  end
42
46
 
43
- end
47
+ describe "with no block" do
44
48
 
45
- describe "with no block" do
49
+ it "returns true if any value is truthy" do
50
+ Hamster.set(nil, false, true, "A").send(method).should be_true
51
+ end
46
52
 
47
- it "returns true if any value is truthy" do
48
- Hamster.set(nil, false, true, "A").any?.should be_true
49
- end
53
+ it "returns false if all values are falsey" do
54
+ Hamster.set(nil, false).send(method).should be_false
55
+ end
50
56
 
51
- it "returns false if all values are falsey" do
52
- Hamster.set(nil, false).any?.should be_false
53
57
  end
54
58
 
55
59
  end
@@ -23,10 +23,10 @@ describe Hamster::Set do
23
23
 
24
24
  end
25
25
 
26
- describe "with no block (external iteration)" do
26
+ describe "with no block" do
27
27
 
28
- it "returns an enumerator over all key value pairs" do
29
- Set[*@set.each.to_a.flatten].should == Set["A", "B", "C"]
28
+ it "returns self" do
29
+ @set.each.should equal(@set)
30
30
  end
31
31
 
32
32
  end
@@ -43,11 +43,11 @@ describe Hamster::Set do
43
43
  describe "with no block" do
44
44
 
45
45
  before do
46
- @enumerator = @original.send(method)
46
+ @result = @original.send(method)
47
47
  end
48
48
 
49
- it "returns an enumerator over the values" do
50
- Hamster.set(*@enumerator.to_a).should == Hamster.set("A", "B", "C")
49
+ it "returns self" do
50
+ @result.should equal(@original)
51
51
  end
52
52
 
53
53
  end
@@ -44,15 +44,11 @@ describe Hamster::Set do
44
44
  describe "with no block" do
45
45
 
46
46
  before do
47
- @enumerator = @original.send(method)
47
+ @result = @original.send(method)
48
48
  end
49
49
 
50
- it "preserves the original values" do
51
- @original.should == Hamster.set("A", "B", "C")
52
- end
53
-
54
- it "returns an enumerator over the values" do
55
- Hamster.set(*@enumerator.to_a).should == @original
50
+ it "returns self" do
51
+ @result.should equal(@original)
56
52
  end
57
53
 
58
54
  end
@@ -41,11 +41,11 @@ describe Hamster::Set do
41
41
  describe "with no block" do
42
42
 
43
43
  before do
44
- @enumerator = @original.reject
44
+ @result = @original.reject
45
45
  end
46
46
 
47
- it "returns an enumerator over the values" do
48
- Hamster.set(*@enumerator.to_a).should == Hamster.set("A", "B", "C")
47
+ it "returns self" do
48
+ @result.should equal(@original)
49
49
  end
50
50
 
51
51
  end
@@ -6,18 +6,14 @@ describe Hamster::Stack do
6
6
  @stack = Hamster.stack.push("A").push("B").push("C")
7
7
  end
8
8
 
9
- describe "#dup" do
9
+ [:dup, :clone].each do |method|
10
10
 
11
- it "returns self" do
12
- @stack.dup.should equal(@stack)
13
- end
14
-
15
- end
11
+ describe "##{method}" do
16
12
 
17
- describe "#clone" do
13
+ it "returns self" do
14
+ @stack.send(method).should equal(@stack)
15
+ end
18
16
 
19
- it "returns self" do
20
- @stack.clone.should equal(@stack)
21
17
  end
22
18
 
23
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hamster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Harris
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-08 00:00:00 +11:00
12
+ date: 2009-12-10 00:00:00 +11:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -59,7 +59,7 @@ files:
59
59
  - spec/hamster/list/filter_spec.rb
60
60
  - spec/hamster/list/head_spec.rb
61
61
  - spec/hamster/list/include_spec.rb
62
- - spec/hamster/list/lazy_spec.rb
62
+ - spec/hamster/list/inspect_spec.rb
63
63
  - spec/hamster/list/map_spec.rb
64
64
  - spec/hamster/list/reduce_spec.rb
65
65
  - spec/hamster/list/reject_spec.rb
@@ -67,6 +67,7 @@ files:
67
67
  - spec/hamster/list/tail_spec.rb
68
68
  - spec/hamster/list/take_spec.rb
69
69
  - spec/hamster/list/take_while_spec.rb
70
+ - spec/hamster/list/to_a_spec.rb
70
71
  - spec/hamster/set/add_spec.rb
71
72
  - spec/hamster/set/all_spec.rb
72
73
  - spec/hamster/set/any_spec.rb
@@ -108,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
109
  requirements:
109
110
  - - ">="
110
111
  - !ruby/object:Gem::Version
111
- version: 1.9.1
112
+ version: 1.8.6
112
113
  version:
113
114
  required_rubygems_version: !ruby/object:Gem::Requirement
114
115
  requirements:
@@ -1,21 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe Hamster::List do
4
-
5
- describe "laziness" do
6
-
7
- def prime?(n)
8
- 2.upto(Math.sqrt(n).round) { |i| return false if n % i == 0 }
9
- true
10
- end
11
-
12
- it "primes" do
13
- numbers = Hamster.interval(10000, 1000000)
14
- primes = numbers.filter { |i| prime?(i) }
15
- primes.take(3)
16
-
17
- end
18
-
19
- end
20
-
21
- end