hamster 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
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