Rubyのfiberに関する質問

このQ&Aのポイント
  • Rubyのfiberについて勉強のためコードを書きましたが、エラーが発生しています。
  • 出力結果が期待通りにならず、`dead fiber called`のエラーが発生しています。
  • どのように修正すれば正常に動作させることができるでしょうか。
回答を見る
  • ベストアンサー

ruby の fiber に関する質問です。

# -*- coding: utf-8 -*- testfile = %w{This is the pen!! This is a dog.} words = Fiber.new do testfile.each do |line| line.scan(/\w+/) do |word| Fiber.yield word.downcase end end end counts = Hash.new(0) while word = words.resume counts[word] += 1 end counts.keys.sort.each {|word| print "#{word}:#{counts[word]} "} とfiberについて勉強のためコードを書きました。 出力結果を a:1 dog:1 is:2 pen:1 the:1 this:2 としたいのですが、 実際やってみると e12-1-1.rb:15:in `resume': dead fiber called (FiberError) from e12-1-1.rb:15:in `<main>' と結果が返ってくるのですが、どのように直せばよいのでしょうかおしえてください。

  • Ruby
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

while word = words.resume でループしようとしていると言うことは、wordsというfiberが終了すれば nil が返ることを期待しているのですか? そうであれば、 words = Fiber.new do testfile.each do |line| line.scan(/\w+/) do |word| Fiber.yield word.downcase end end nil end 元のままだと、words.resumeの最終回は、testfile.each do ~ end の結果つまり、testfile が返るので、resumeで受け取ったあとのwhileが終了しません。

zerozero5320
質問者

お礼

nil を返さないとresumeが終了しないのですね。早速やってみてうまくいきました。ありがとうございます。

関連するQ&A

  • Rubyについて質問です

    Rubyについて質問です class Document #省略 def each_word word_array = words index = 0 while index < words.size yield(word_array[index]) index += 1 end end end d = Document.new('Truth', 'Gump', 'Life is like a box of...') d.each_word { |word| puts word } このような例題があるのですが、 このまま実行しても引数エラーがでてしまいます。 「省略」のところをどのように追加すれば実行できるようになりますか? 参考書:ELOQUENT RUBYの中の例題です ちなみに実行結果は以下の通りです Life is like a box of ... どうかよろしくお願いいたします

  • Ruby について質問です

    Rubyについて質問です class Document include Enumerable attr_accessor :title, :author, :content def initialize(title, author, content) @title = title @author = author @content = content end def words @content.split end def each words.each { |word| yield(word) } end end doc = Document.new('Advice', 'Harry', 'Go ahead make my day') doc.each { |word| puts word } このようなコードがすでに出来上がったおり、 これをアルファベットの早い順に並び変えて(sort)出力させるには どのようにコードを追加すればよいですか? どうやら、sort メソッドと <=> 演算子を使って記述するようですが、 よくわかりません 回答お願いいたします。

  • ハッシュ(単語数を数える) たのしいRuby

    たのしいRuby P252に掲載されていた、例題 「ハッシュ(単語数を数える)」の解説を読んでも 意味が分からなかったので教えてください。 ■例題word_count.rb 1:# 単語数のカウント 2: 3: count = Hash.new(0) 4: 5:## 単語の集計 6:while line = gets 7: words = line.split 8: words.each{|word| 9: count[word] += 1 10: } 11:end 12: 13:## 結果の出力 14:count.sort{|a,b| 15: a[1] <=> b[1] 16:}.each{|key, value| 17: print "#{key}: #{value}\n" 18} ■疑問1. 解説には、 # 3行目で出現回数を記録するハッシュcountを作ります。 # countは、キーが単語、値がその単語が出現した回数を表します。 と書かれているのですが、「キーが単語、値がその単語が出現した回数を表します」 の内容が理解できません。newしただけなのに、どうして、 キーと値の内容が決まるのでしょうか? ■疑問2. 解説には、 # 8行目からの繰り返しでは、それぞれの単語をキーにして、countから出現回数を取り出し、 # +1します。 と書かれているのですが、「count[word] += 1」 の内容が理解できません。 作成したハッシュcountと、getsメソッドで読み込み単語単位に分割した配列wordsとが、 どこで関連付けされているのかが、分かりません。 ■疑問3. 解説には、 # ruby word_count.rb README という形で、Rubyに同梱されているREADMEファイルの単語数を調べた 実行結果が掲載されているのですが、 そのときの具体的な処理の流れが分かりません。 「ruby word_count.rb README」と書くだけで、 処理の流れが、getsの所まできたとき、 自動的に指定ファイル名を判断し、 読み込みを始めるということなのでしょうか。

    • ベストアンサー
    • Ruby
  • Ruby 暗号化したファイルの復号について

    Rubyでファイルを暗号化し、それを復号したいのですがうまくいかないため、 質問させていただきます。 Ruby 1.9.3を使用しています。 ・ファイルの暗号化 encrypt.rb ------------------------------------------------- # encoding: cp932 require 'openssl' def encrypt(file, pass)   enc = OpenSSL::Cipher::AES256.new('CBC')   enc.encrypt   enc.pkcs5_keyivgen(pass)   File.open(file, 'rb') do |fin|     File.open("#{file}.sec", 'wb') do |fout|       while buff = fin.read(8000)         fout.write(enc.update(buff))       end       fout.write(enc.final)     end   end   enc.reset end if $*.length > 0   print 'password: '   pass = $stdin.gets.chomp   $*.each do |arg|     begin       encrypt(arg, pass)       puts "#{arg}を暗号化したファイル#{arg}.secを作りました。"     rescue       puts "#{arg}の暗号化に失敗しました。"     end   end   0.upto(pass.length - 1) do |i|     pass[i] = '\xff'   end end ------------------------------------------------- ・ファイルの復号 decrypt.rb ------------------------------------------------- # encoding: cp932 def decrypt(file, pass)   dec = OpenSSL::Cipher::AES256.new('CBC')   dec.decrypt   dec.pkcs5_keyivgen(pass)   File.open(file, 'rb') do |fin|     File.open("#{file}.plain", 'wb') do |fout|       while buff = fin.read(512)         fout.write(dec.update(buff))       end       fout.write(dec.final)     end   end   dec.reset end if $*.length > 0   print 'password: '   pass = $stdin.gets.chomp   $*.each do |arg|     begin       decrypt(arg, pass)       puts "#{arg}を復号したファイル#{arg}.plainを作りました。"     rescue       puts "#{arg}の復号に失敗しました。"     end   end   0.upto(pass.length - 1) do |i|     pass[i] = '\xff'   end end ------------------------------------------------- コマンドプロンプトでencrypt.rb自身を暗号化し、encrypt.rb.secの作成はできるのですが、 decrypt.rbを実行してパスワードを入力しても復号ができません。 どのようにすれば復号できるのか教えていただけますでしょうか。

    • ベストアンサー
    • Ruby
  • 【ruby】無名関数?でブロック付きメソッドって作れませんか?

    Proc.new do|arg|  arg.each do |x|   puts x  end end.call([1,2,3,4,5]) 上記のようなものを無名関数と理解しているのですが、 これを下記の様にすると、 Proc.new {|arg|  arg.each do |x|   yield(x)  end }.call([1,2,3,4,5]) do |x|  puts x end no block given とエラーになってしまいます。 無名関数で、ブロック付きメソッドって作れないものでしょうか? ご指導の程、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • Ruby の 文法に困ってます。

    以下のようなソースの場合、to_sメソッドは何時呼ばれているのでしょうか。またどういう意味を成しているのでしょうか。 Ruby初心者のためご教授頂けないでしょうか。 よろしくお願いします。 class Vector   attr_accessor :x, :y   def initialize(x=0, y=0)     @x = x     @y = y   end   def length     Math::sqrt(@x ** 2 + @y ** 2)   end   def to_s      "(#{@x},#{@y})"   end   def <=> other     length <=> other.length   end end arr =[] arr << Vector.new(2,2) arr << Vector.new(3,2) arr << Vector.new arr.sort.each do |item|   puts item end 結果は以下になります。 (0,0) (2,2) (3,2)

    • ベストアンサー
    • Ruby
  • 【Ruby】マルチスレッドでなくマルチプロセスで

    以下の様なプログラムをマルチスレッドでなくマルチプロセスで実現したいです。 #!/usr/bin/ruby require 'thread' q=Queue.new data=%w(a * * * b * * c * * d * *) data.each do |d| q.push d end (1..4).each do |n| Thread.start { while 1 do d=q.shift break if d!='*' end puts n.to_s+' '+d.to_s }.join end rubyのバーションは ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin10.0] です。バージョンをあげる事は、できれば避けたいです。 実際には上記プログラムの【puts n.to_s+' '+d.to_s】してる所は、ネットに繋いで云々の時間のかかる処理なのですが、まったくパラレルに行なっている様子が無いので、マルチプロセス化したら早くなるかなと思いました。 子プロセスを生成して親プロセスとはパイプで繋いで、、などとするのかなあと試行錯誤したのですが、どうもうまくできません。 ご指導の程、よろしくお願い申し上げます。

    • ベストアンサー
    • Ruby
  • rubyでパケットキャプチャ出来るプログラムを実行したところ、以下のよ

    rubyでパケットキャプチャ出来るプログラムを実行したところ、以下のようなエラーメッセージが出力されました。 上位4つのwaraningとno suitable device foundのエラーを回避する策を教えて頂きたいです。 $ ruby packet.rb /usr/local/lib/site_ruby/1.8/i486-linux/pcap.so: warning: do not use Fixnums as Symbols /usr/local/lib/site_ruby/1.8/i486-linux/pcap.so: warning: do not use Fixnums as Symbols /usr/local/lib/site_ruby/1.8/i486-linux/pcap.so: warning: do not use Fixnums as Symbols /usr/local/lib/site_ruby/1.8/pcaplet.rb:41:in `lookupdev': no suitable device found (Pcap::PcapError) from /usr/local/lib/site_ruby/1.8/pcaplet.rb:41:in `initialize' from packet.rb:12:in `new' from packet.rb:12 プログラムは、以下のサイトにあるものを利用しています。 http://d.hatena.ne.jp/tullio/20080217/1203261760 #!/usr/local/bin/ruby require 'pcaplet' include Pcap class Time # tcpdump style format def to_s sprintf "%0.2d:%0.2d:%0.2d.%0.6d", hour, min, sec, tv_usec end end pcaplet = Pcaplet.new pcaplet.each_packet { |pkt| print "#{pkt.time} #{pkt}" if pkt.tcp? print " (#{pkt.tcp_data_len})" print " ack #{pkt.tcp_ack}" if pkt.tcp_ack? print " win #{pkt.tcp_win}" end if pkt.ip? print " (DF)" if pkt.ip_df? end print "\n" } pcaplet.close 以上、宜しくお願い致します。

  • ruby+xml 特定の属性値をもつ要素の求め方

    宜しくお願いします。 ↓のようなxmlファイルがあり、 #########hoge.xml############# <root> <a name="a1"> <b>bbb1</b> <b>bbb2</b> <b>bbb3</b> <c>ccc1</c> </a> <a> <b>bbb4</b> <b>bbb5</b> </a> <a name="a3" price="100"></a> </root> ###################### ↓と同じ処理をしたいのですが、 doc = REXML::Document.new(open("hoge.xml")) doc.elements.each("root/a[@name='a1']/b") do |element| ... end a1が変数名の場合、 どのように記述したらよいのでしょうか。 doc = REXML::Document.new(open("hoge.xml")) attr = a1 doc.elements.each("root/a[@name='????????']/b") do |element| ... end 基本的な内容で申し訳ありませんが、 宜しくお願いします。

    • ベストアンサー
    • Ruby
  • rubyの繰り返し処理の仕方を教えてください

    rubyの繰り返し処理の仕方がわかりません rubyを使ってのプログラムを勉強してます。最終的には表の書き換えをする プログラムがつくりたいのですが最初でコケましたruby イテレーター ネストで検索してもわからなかったので質問します。どなたか お時間あれ ば教えてください。 お店の番号SA003とSA005を次の "SA001",0,10,20,10 "SA003",0,10,20,20 "SA004",0,10,20,100 "SA005",0,10,20,50 の表なかから探すプログラムを作成しようとしましたが。 繰り返し処理の仕方がわかりません変数のスコープが外れていると思いますし dataの行数は4とはかぎらないので 4.times は使えないのはわかるのですが とりあえずイメージ的に描いたプログラムです。よろしくお願いいたします。 ====testimage.rb======== class Shop_number def initialize @mise=["SA003","SA005"] end def tenposuu() return @mise.size end def tenpo_no(n) return @mise[n] end end data =[["SA001",0,10,20,10],["SA003",0,10,20,20],["SA004",0,10,20,100],["SA005",0,10,20,50]] obj = Shop_number.new obj.tenposuu.times do |i| 4.times do |j| if data[j][0]=~/{obj.tenpo_no(i)}/ then puts data end end ======================= =>["SA003",0,10,20,20] =>["SA005",0,10,20,50] と出したいのですが・・・

    • ベストアンサー
    • Ruby