59. Mutex
n = 0
mutex = Mutex.new
def increment(v)
v + 1
end
2.times do
Thread.new {
1_000_000.times {
mutex.synchronize { n = increment(n) }
}
}
end
Friday, November 5, 2010
60. Mutex
n = 0
mutex = Mutex.new
def increment(v)
v + 1
end
2.times do
Thread.new {
1_000_000.times {
mutex.synchronize { n = increment(n) }
}
}
end
Friday, November 5, 2010
76. list = %w{ a b }
iter = Enumerator.new(list)
iter.next # => a
iter.next # => b
iter.next # raises StopIteration
Friday, November 5, 2010
77. list = %w{ a b }
iter = Enumerator.new(list)
begin
3.times do
iter.next
end
rescue StopIteration => e
p e.result
end
Friday, November 5, 2010
78. list = %w{ a b }
iter = Enumerator.new(list)
begin
3.times do
iter.next
end
rescue StopIteration => e
p e.result # => ["a", "b"]
end
Friday, November 5, 2010
83. list = %w{ a b }
iter = Enumerator.new(list, :map)
x = iter.each do |thing|
thing + " hello!"
end
p x
Friday, November 5, 2010
84. list = %w{ a b }
iter = Enumerator.new(list, :map)
x = iter.each do |thing|
thing + " hello!"
end
p x # => ["a hello!", "b hello!"]
Friday, November 5, 2010
85. list = %w{ a b }
iter = Enumerator.new(list, :map)
x = iter.each_with_index do |thing, i|
thing + ":#{i}"
end
p x
Friday, November 5, 2010
86. list = %w{ a b }
iter = Enumerator.new(list, :map)
x = iter.each_with_index do |thing, i|
thing + ":#{i}"
end
p x # => ["a:0", "b:1"]
Friday, November 5, 2010
97. Node
class Node < Struct.new(:children)
def initialize(children = [])
super
end
end
Friday, November 5, 2010
98. Bottom Up
class DepthFirst < Struct.new(:tree)
def each(&block)
iterate(tree, block)
end
private
def iterate(node, block)
node.children.each { |n|
iterate(n, block)
}
block.call node
end
end
Friday, November 5, 2010
101. Top Down
class TopDown < Struct.new(:tree)
def each(&block)
iterate(tree, block)
end
private
def iterate(node, block)
block.call node
node.children.each { |n|
iterate(n, block)
}
end
end
Friday, November 5, 2010
104. Node
class Node < Struct.new(:children)
def initialize(children = [])
super
end
def each(&block)
return enum_for(:each) unless block_given?
DepthFirst.new(self).each(&block)
end
end
Friday, November 5, 2010
105. Parallel Iteration
iter = tree1.each
tree2.all? { |node| node == iter.next }
Friday, November 5, 2010
108. class Infinity
include Enumerable
def each
return enum_for(:each) unless block_given?
i = 0
loop do
yield i
i += 1
end
end
end
Friday, November 5, 2010
116. pi = Enumerator.new do |yielder|
root_12 = Math.sqrt(12)
pi = 0
infinity.each do |k|
pi += (-1 / 3.0) ** k / (2 * k + 1).to_f
yielder << (root_12 * pi)
end
end
Friday, November 5, 2010
117. pi = Enumerator.new do |yielder|
root_12 = Math.sqrt(12)
pi = 0
infinity.each do |k|
pi += (-1 / 3.0) ** k / (2 * k + 1).to_f
yielder << (root_12 * pi)
end
end
Friday, November 5, 2010
147. class Foo < Psych::Handler
def start_document(...)
...
end
def end_document(...)
...
end
end
SAX Style Handler
Friday, November 5, 2010
148. Event Handler
class EventHandler
def initialize(fiber)
@fiber = fiber
end
def method_missing(name, *args)
@fiber.resume(name, args)
end
end
Friday, November 5, 2010
149. fiber = Fiber.new do |method, args|
stack = []
loop do
case method
when :start_mapping
stack << []
when :end_mapping
h = Hash[*stack.pop]
if stack.empty?
p h
else
stack.last << h
end
when :scalar
stack.last << args.first
end
method, args = Fiber.yield
end
end
Friday, November 5, 2010
150. case method
when :start_mapping
stack << []
when :end_mapping
h = Hash[*stack.pop]
if stack.empty?
stdout.resume h
else
stack.last << h
end
when :scalar
stack.last << args.first
end
method, args = Fiber.yield
Friday, November 5, 2010
151. StdOut Fiber
stdout = Fiber.new do |obj|
loop do
p obj
obj = Fiber.yield
end
end
Friday, November 5, 2010
164. Slow Consumer
slow = Fiber.new do
loop do
while !queue.empty?
sleep 1
puts "########### slow: " + queue.pop
Fiber.yield
end
Fiber.yield
end
end
Friday, November 5, 2010
165. Random Scheduler
fibers = [producer, hungry, slow]
loop do
fibers.sort_by { rand }.each do |fiber|
fiber.resume
end
end
Friday, November 5, 2010
173. class SimpleEnum
def initialize &block
@fiber = Fiber.new do
block.call(self)
end
end
def << value
Fiber.yield value
end
def next
@fiber.resume
end
end
Friday, November 5, 2010
174. infinity = SimpleEnum.new do |yielder|
i = 0
loop do
yielder << i
i += 1
end
end
Friday, November 5, 2010
191. class Pipe < Struct.new(:source)
def initialize(source = nil)
super
@fiber = Fiber.new { self.loop }
end
def loop
while value = read
process value
end
end
def read; source.resume end
def write(value); Fiber.yield(value) end
def process(value); write(value) end
def resume; @fiber.resume end
end
Friday, November 5, 2010
192. class Infinity < Pipe
def loop
i = 0
while true
write i
i += 1
end
end
end
InïŹnity (again)
Friday, November 5, 2010
193. Evens
class Evens < Pipe
def process(value)
super if value % 2 == 0
end
end
Friday, November 5, 2010
194. StdOut
class StdOut < Pipe
def write value
puts value
end
end
Friday, November 5, 2010
209. ERb Pipe
class PipERB < Pipe
def initialize data
super()
@erb = ERB.new(data, nil, nil, 'self')
end
alias :concat :process
def read; @erb.result(binding) end
def force_encoding encoding; end
end
Friday, November 5, 2010
212. Slow Template
<ul>
<% a = b = 1 %>
<% 10.times do %>
<li><%= a %></li>
<% sleep(1) # simulate work %>
<% a, b = b, a + b %>
<% end %>
</ul>
Friday, November 5, 2010
213. Normal Handler
class ERBHandler
def initialize
@fib_template = DATA.read
end
def call env
result = [
ERB.new(@fib_template).result(binding)
]
[ 200, {'X-Hello' => 'World'}, result ]
end
end
Friday, November 5, 2010
216. Each Pipe
class Each < Pipe
def each(&block)
@block = block
resume
end
def process(value)
@block.call(value)
end
end
Friday, November 5, 2010
217. Each Pipe
(PipERB.new(DATA.read) | Each.new).each do |chunk|
print chunk
end
__END__
<ul>
<% a = b = 1 %>
<% 10.times do %>
<li><%= a %></li>
<% sleep 1; a, b = b, a + b %>
<% end %>
</ul>
Friday, November 5, 2010
218. Each Pipe
(PipERB.new(DATA.read) | Each.new).each do |chunk|
print chunk
end
__END__
<ul>
<% a = b = 1 %>
<% 10.times do %>
<li><%= a %></li>
<% sleep 1; a, b = b, a + b %>
<% end %>
</ul>
Friday, November 5, 2010
219. Fiber Handler
class ERBHandler
def initialize
@fib_template = DATA.read
end
def call env
[ 200, {},
(PipERB.new(@fib_template) | Each.new)
]
end
end
Friday, November 5, 2010