Rubyのfiberに関する質問
- 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>' と結果が返ってくるのですが、どのように直せばよいのでしょうかおしえてください。
- zerozero5320
- お礼率44% (4/9)
- Ruby
- 回答数1
- ありがとう数1
- みんなの回答 (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が終了しません。
関連する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
- 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
お礼
nil を返さないとresumeが終了しないのですね。早速やってみてうまくいきました。ありがとうございます。