Class: Chan
- Inherits:
-
Object
- Object
- Chan
- Defined in:
- lib/chan.rb
Overview
Chan: Bidirectional enumerator (channel) or the chan object like in Golang
Copyright © 2015, T. Yamada under Ruby License (2-clause BSDL or Artistic).
Check LICENSE terms.
Note: MIT License is also applicable if that compresses LICENSE file.
Defined Under Namespace
Classes: Yielder
Constant Summary collapse
- VERSION =
VERSION string
'0.0.0.1'
Instance Method Summary collapse
-
#gen_enum(enum) ⇒ Object
Builds an Enumerator using existing Enumerator.
-
#initialize(&blk) ⇒ Chan
constructor
Constructor.
-
#next? ⇒ Boolean
Tells if the channel has next element.
-
#peek ⇒ Object
Receives an object from child without modifying the queue.
-
#receive ⇒ Object
(also: #next, #succ)
Receives an object from child.
-
#send(v) ⇒ Object
(also: #<<)
Sends an object to child.
Constructor Details
#initialize(&blk) ⇒ Chan
Constructor. you should pass a block like you do in Enumerator. Actually if you use Enumerator.new{} as external iterator, you can safely convert it to Chan.new{} in most cases.
58 59 60 61 62 63 64 65 66 |
# File 'lib/chan.rb', line 58 def initialize(&blk) @f=Fiber.new{|parent_to_child,child_to_parent,blk| ch=Yielder.new(parent_to_child,child_to_parent) blk.call(ch) } @parent_to_child=[] @child_to_parent=[] @f.resume(@parent_to_child,@child_to_parent,blk) end |
Instance Method Details
#gen_enum(enum) ⇒ Object
Builds an Enumerator using existing Enumerator.
103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/chan.rb', line 103 def gen_enum(enum) Enumerator.new{|y| begin loop{ self<<enum.next y<<self.receive if self.next? } # StopIteration is catched by Kernel#loop rescue RuntimeError # attempted to push to closed Chan end y<<self.receive while self.next? } end |
#next? ⇒ Boolean
Tells if the channel has next element. If false, it means end of enumeration or you need to give more object.
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/chan.rb', line 70 def next? while @child_to_parent.empty? begin flg=@f.resume if flg&&@parent_to_child.empty? return false end rescue FiberError return false end end true end |
#peek ⇒ Object
Receives an object from child without modifying the queue.
84 85 86 87 |
# File 'lib/chan.rb', line 84 def peek raise StopIteration.new('too many read requests') if !next? @child_to_parent.first end |
#receive ⇒ Object Also known as: next, succ
Receives an object from child. aliased to next/succ.
90 91 92 93 |
# File 'lib/chan.rb', line 90 def receive raise StopIteration.new('too many read requests') if !next? @child_to_parent.shift end |
#send(v) ⇒ Object Also known as: <<
Sends an object to child.
97 98 99 |
# File 'lib/chan.rb', line 97 def send(v) @parent_to_child.push(v) end |