hamster 0.2.3 → 0.2.4

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/History.rdoc CHANGED
@@ -1,3 +1,15 @@
1
+ === 0.2.4 / 2010-01-18
2
+
3
+ * Fix List#cadr and friends under JRuby.
4
+
5
+ * Remove redundant locking (speed up).
6
+
7
+ * Make reverse "lazy" (ish).
8
+
9
+ * Fixed: StackOverflow calling List#head and List#tail on very large lazy lists.
10
+
11
+ * Alias #reduce as #foldr.
12
+
1
13
  === 0.2.3 / 2010-01-18
2
14
 
3
15
  * Implement Set#group_by.
data/lib/hamster/hash.rb CHANGED
@@ -77,6 +77,7 @@ module Hamster
77
77
  end
78
78
  def_delegator :self, :reduce, :inject
79
79
  def_delegator :self, :reduce, :fold
80
+ def_delegator :self, :reduce, :foldr
80
81
 
81
82
  def filter
82
83
  return self unless block_given?
data/lib/hamster/list.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'forwardable'
2
- require 'monitor'
2
+ require 'thread'
3
3
 
4
4
  require 'hamster/tuple'
5
5
  require 'hamster/hash'
@@ -99,6 +99,7 @@ module Hamster
99
99
  end
100
100
  def_delegator :self, :reduce, :inject
101
101
  def_delegator :self, :reduce, :fold
102
+ def_delegator :self, :reduce, :foldr
102
103
 
103
104
  def filter(&block)
104
105
  return self unless block_given?
@@ -251,7 +252,9 @@ module Hamster
251
252
  def_delegator :self, :append, :+
252
253
 
253
254
  def reverse
254
- reduce(EmptyList) { |list, item| list.cons(item) }
255
+ Stream.new do
256
+ reduce(EmptyList) { |list, item| list.cons(item) }
257
+ end
255
258
  end
256
259
 
257
260
  def minimum(&block)
@@ -492,13 +495,13 @@ module Hamster
492
495
  end
493
496
 
494
497
  def respond_to?(name, include_private = false)
495
- super || CADR === name
498
+ super || CADR === name.to_s
496
499
  end
497
500
 
498
501
  private
499
502
 
500
503
  def method_missing(name, *args, &block)
501
- if CADR === name
504
+ if CADR === name.to_s
502
505
  accessor($1)
503
506
  else
504
507
  super
@@ -543,7 +546,7 @@ module Hamster
543
546
 
544
547
  def initialize(&block)
545
548
  @block = block
546
- @mutex = Mutex.new
549
+ @lock = Mutex.new
547
550
  end
548
551
 
549
552
  def head
@@ -555,18 +558,23 @@ module Hamster
555
558
  end
556
559
 
557
560
  def empty?
558
- list = target
559
- while list.is_a?(Stream)
560
- list = list.target
561
- end
562
- list.empty?
561
+ target.empty?
563
562
  end
564
563
 
565
564
  protected
566
565
 
567
566
  def target
568
- @mutex.synchronize do
569
- unless defined?(@target)
567
+ # conjure
568
+ list = conjure
569
+ while list.is_a?(Stream)
570
+ list = list.conjure
571
+ end
572
+ list
573
+ end
574
+
575
+ def conjure
576
+ @lock.synchronize do
577
+ unless @block.nil?
570
578
  @target = @block.call
571
579
  @block = nil
572
580
  end
data/lib/hamster/set.rb CHANGED
@@ -75,6 +75,7 @@ module Hamster
75
75
  end
76
76
  def_delegator :self, :reduce, :inject
77
77
  def_delegator :self, :reduce, :fold
78
+ def_delegator :self, :reduce, :foldr
78
79
 
79
80
  def filter
80
81
  return self unless block_given?
@@ -1,5 +1,5 @@
1
1
  module Hamster
2
2
 
3
- VERSION = "0.2.3".freeze
3
+ VERSION = "0.2.4".freeze
4
4
 
5
5
  end
@@ -4,7 +4,7 @@ require 'hamster/hash'
4
4
 
5
5
  describe Hamster::Hash do
6
6
 
7
- [:reduce, :inject, :fold].each do |method|
7
+ [:reduce, :inject, :fold, :foldr].each do |method|
8
8
 
9
9
  describe "##{method}" do
10
10
 
@@ -4,23 +4,27 @@ require 'hamster/list'
4
4
 
5
5
  describe Hamster::List do
6
6
 
7
- describe "#cadr" do
8
-
9
- [
10
- [[], :car, nil],
11
- [["A"], :car, "A"],
12
- [["A", "B", "C"], :car, "A"],
13
- [["A", "B", "C"], :cadr, "B"],
14
- [["A", "B", "C"], :caddr, "C"],
15
- [["A", "B", "C"], :cadddr, nil],
16
- [["A", "B", "C"], :caddddr, nil],
17
- [[], :cdr, Hamster.list],
18
- [["A"], :cdr, Hamster.list],
19
- [["A", "B", "C"], :cdr, Hamster.list("B", "C")],
20
- [["A", "B", "C"], :cddr, Hamster.list("C")],
21
- [["A", "B", "C"], :cdddr, Hamster.list],
22
- [["A", "B", "C"], :cddddr, Hamster.list],
23
- ].each do |values, method, expected|
7
+ [
8
+ [[], :car, nil],
9
+ [["A"], :car, "A"],
10
+ [["A", "B", "C"], :car, "A"],
11
+ [["A", "B", "C"], :cadr, "B"],
12
+ [["A", "B", "C"], :caddr, "C"],
13
+ [["A", "B", "C"], :cadddr, nil],
14
+ [["A", "B", "C"], :caddddr, nil],
15
+ [[], :cdr, Hamster.list],
16
+ [["A"], :cdr, Hamster.list],
17
+ [["A", "B", "C"], :cdr, Hamster.list("B", "C")],
18
+ [["A", "B", "C"], :cddr, Hamster.list("C")],
19
+ [["A", "B", "C"], :cdddr, Hamster.list],
20
+ [["A", "B", "C"], :cddddr, Hamster.list],
21
+ ].each do |values, method, expected|
22
+
23
+ describe "##{method}" do
24
+
25
+ it "is responded to" do
26
+ Hamster.list.respond_to?(method).should == true
27
+ end
24
28
 
25
29
  describe "on #{values.inspect}" do
26
30
 
@@ -29,10 +33,6 @@ describe Hamster::List do
29
33
  @result = @original.send(method)
30
34
  end
31
35
 
32
- it "responds to #{method}" do
33
- @original.respond_to?(method, false).should == true
34
- end
35
-
36
36
  it "preserves the original" do
37
37
  @original.should == Hamster.list(*values)
38
38
  end
@@ -6,6 +6,18 @@ describe Hamster::List do
6
6
 
7
7
  [:head, :first].each do |method|
8
8
 
9
+ describe "on a really big list" do
10
+
11
+ before do
12
+ @list = Hamster.interval(0, STACK_OVERFLOW_DEPTH)
13
+ end
14
+
15
+ it "doesn't run out of stack" do
16
+ lambda { @list.filter(&:nil?).head }.should_not raise_error
17
+ end
18
+
19
+ end
20
+
9
21
  describe "##{method}" do
10
22
 
11
23
  [
@@ -4,7 +4,7 @@ require 'hamster/list'
4
4
 
5
5
  describe Hamster::List do
6
6
 
7
- [:reduce, :inject, :fold].each do |method|
7
+ [:reduce, :inject, :fold, :foldr].each do |method|
8
8
 
9
9
  describe "##{method}" do
10
10
 
@@ -18,6 +18,10 @@ describe Hamster::List do
18
18
 
19
19
  end
20
20
 
21
+ it "is lazy" do
22
+ lambda { Hamster.stream { fail }.reverse }.should_not raise_error
23
+ end
24
+
21
25
  [
22
26
  [[], []],
23
27
  [["A"], ["A"]],
@@ -6,6 +6,18 @@ describe Hamster::List do
6
6
 
7
7
  describe "#tail" do
8
8
 
9
+ describe "on a really big list" do
10
+
11
+ before do
12
+ @list = Hamster.interval(0, STACK_OVERFLOW_DEPTH)
13
+ end
14
+
15
+ it "doesn't run out of stack" do
16
+ lambda { @list.filter(&:nil?).tail }.should_not raise_error
17
+ end
18
+
19
+ end
20
+
9
21
  [
10
22
  [[], []],
11
23
  [["A"], []],
@@ -4,7 +4,7 @@ require 'hamster/set'
4
4
 
5
5
  describe Hamster::Set do
6
6
 
7
- [:reduce, :inject, :fold].each do |method|
7
+ [:reduce, :inject, :fold, :foldr].each do |method|
8
8
 
9
9
  describe "##{method}" do
10
10
 
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.2.3
4
+ version: 0.2.4
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: 2010-01-18 00:00:00 +11:00
12
+ date: 2010-01-19 00:00:00 +11:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency