2002-03-22 [長年日記]
λ. 論文読み会 “Virtualizing I/O Devices on VMware Workstation's Hosted Virtual Machine Monitor”
面白かったけど、やはりこういう方面はちとつらい。OSの理論とかをもうちょっとちゃんと勉強しておいた方が良いかもしれないなと思った。
λ. Enumerable.join
こんなのいかが?
module Enumerable def self.join(*items) Concatenation.new(*items) end class Concatenation include Enumerable def initialize(*items) @items = items end def each(&block) @items.each{|i| i.each(&block)} end end end
λ. フィボナッチ数列
上のを使ってRubyらしからぬコードを書いてみた。……でも動かないや。原因はGeneratorが先読みしてしまっている事(だと思う)。つまり、generator.rbをここまでアホな用途に使った奴はこれまでいなかったということか。ワハハ。
class <<Fib = Object.new.extend(Enumerable) def each yield 1 SyncEnumerator.new(self, Enumerable.join([0], self)).each{|a,b| yield(a + b) } end end
λ. ムネオ
世間ではムネオという議員の事が取りざたされているようだ。最近すっかり世相に疎くなってしまった。
この sync_each を使ったらうまくいきました。でも、新しい値<br>を計算するのに、過去の値を全て再計算させるので、大変よろし<br>くないですなあ。:-)<br>require "enum-join"<br><br>def Enumerable.sync_each(*a)<br> a.size.zero? and return<br> <br> thrgr = ThreadGroup.new<br> values = Array.new(a.size)<br> count = 0<br> <br> a.each_with_index do |e, i|<br> thrgr.add(Thread.new(e, i){|e0, i0|<br> e0.each do |f|<br> values[i0] = f<br> Thread.critical = true<br> count += 1<br> Thread.stop<br> end<br> })<br> end<br> <br> while thrgr.list.size >= a.size<br> if count >= a.size<br> yield values<br> count = 0<br> thrgr.list.each{|t| t.wakeup}<br> end<br> Thread.pass<br> end<br>end<br><br>class << Fib = Object.new.extend(Enumerable)<br> def each<br> yield 1<br> Enumerable.sync_each(self, Enumerable.join([0],<br>self)){|a,b|<br> yield(a + b)<br> }<br> end<br>end<br><br>Fib.each do |x|<br> p x<br>end
おぉ。さすが原さん。<br>ThreadGroupってこうやって使うのですね。<br><br>> でも、新しい値を計算するのに、過去の値を全て再計算させるので、<br>> 大変よろしくないですなあ。:-)<br><br>笑。
>ThreadGroupってこうやって使うのですね。<br><br>いやあ、私もThreadGroupを使ったことなかったんです。^^;<br>でもこの使い方はイテレータブロックでさらにスレッドを起こす<br>ケースで問題がある場合もあるので、ThreadGroupなしバージョ<br>ンをここに置きました。<br><br>http://www.rubycookbook.org/showrecipe.rb?recipeID=190