A Strolling Programmeraka なかだ

またの名を「風まかせ人まかせ力まかせ」日記

T D I A R Y T I M E S % fgrep -i '' *.td2
<< 2005/08/ 1 2 3 1. 全部リンクしたruby
4 1. 全部リンクしたruby(2)
5 1. goal postとbit or
6 1. 里帰り
7 1. 里帰り帰り
2. るびまインタビュー
8 9 1. 夏
10 1. Ruby のバグ(勝手に)トラッカー
2. ブロックなしのzsuper
11 1. close後のStringIO#string
2. Wikipedia
12 13 14 15 16 17 1. Fixnum#==
2. 自動改札機を置いてるビル
18 1. スタックオーバーフローのハンドリング
19 1. css-mode.el
20 1. 事故
21 22 1. @age += 1だった件
23 1. 日本気球連盟
2. 予定
3. 日本OSS貢献者賞
24 25 26 27 1. Language Update
2. フレームワーク対決
3. キミならどう書く
4. 花園神社経由大久保公園
28 29 1. ls -d
30 31 1. protoize
2. protoize (2)
3. バス時刻表
>>
«前の日記(2005-08-10) 最新 次の日記(2005-08-17)» 編集

2005-08-11 modified at Sat Aug 13 15:52:04 2005

* [ruby] close後のStringIO#string

あまり考えていなかったけれど、closeしてもそのまま取り出せたほうがいいのかな? この例でいうと、元々こういう使い方を想定していたんだけど。

def foo(str)
  gz = Zlib::GzipWriter.new(StringIO.new(buff = ""))
  gz.write(str)
  gz.finish
  buff
end

直すの自体は簡単。

Index: ext/stringio/stringio.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/stringio/stringio.c,v
retrieving revision 1.42
diff -U2 -p -r1.42 stringio.c
--- ext/stringio/stringio.c	30 Apr 2005 04:11:10 -0000	1.42
+++ ext/stringio/stringio.c	11 Aug 2005 06:32:14 -0000
@@ -383,8 +383,7 @@ strio_close(self)
 {
     struct StringIO *ptr = StringIO(self);
-    if (CLOSED(ptr)) {
+    if (CLOSED(ptr) || !(ptr->flags & FMODE_READWRITE)) {
 	rb_raise(rb_eIOError, "closed stream");
     }
-    ptr->string = Qnil;
     ptr->flags &= ~FMODE_READWRITE;
     return Qnil;
@@ -406,7 +405,5 @@ strio_close_read(self)
 	rb_raise(rb_eIOError, "closing non-duplex IO for reading");
     }
-    if (!((ptr->flags &= ~FMODE_READABLE) & FMODE_READWRITE)) {
-	ptr->string = Qnil;
-    }
+    ptr->flags &= ~FMODE_READABLE;
     return Qnil;
 }
@@ -427,7 +424,5 @@ strio_close_write(self)
 	rb_raise(rb_eIOError, "closing non-duplex IO for writing");
     }
-    if (!((ptr->flags &= ~FMODE_WRITABLE) & FMODE_READWRITE)) {
-	ptr->string = Qnil;
-    }
+    ptr->flags &= ~FMODE_WRITABLE;
     return Qnil;
 }

* [balloon] Wikipedia

Wikipediaに登録されてるとは気づかなんだ。 しかし、やけに詳しいな。 ついでにCategory:気球にはメジャーな競技の説明まであるし。

本日のツッコミ(全5件) [ツッコミを入れる]
_ akr (2005-08-11 16:11)

以前、string が nil かどうかを close されてるかどうかの判断に使っているという話を聞いた気が。

_ なかだ (2005-08-11 16:59)

flagsを使うようにかえてみました。

_ arton (2005-08-12 02:57)

なるほど。コンストラクタに与えておけば良いのか。
最初に引っかかったのはJavaのStringStreamとかからの類推だけど、gzipみたいにfinish!=closeを用意していない書き手が相手だとclose後も取り出せるほうが良いかも知れません。

_ akr (2005-08-13 13:47)

s = StringIO.new; s.close; p s.closed #=> false

_ akr (2005-08-13 15:52)

つい string が参照されるところを一通り見てしまったのですが、
せっかくなので string は nil にならないようにしたほうがいいかもしれませんね。

% ./ruby -rstringio -e 's = StringIO.new; s.string = nil; s.seek(10, IO::SEEK_END)'
-e:1: [BUG] Segmentation fault
ruby 1.9.0 (2005-08-13) [i686-linux]

% ./ruby -rstringio -e 's = StringIO.new("abc"); s.each_byte {|b| s.string = nil }'
-e:1: [BUG] Segmentation fault
ruby 1.9.0 (2005-08-13) [i686-linux]

% ./ruby -rstringio -e '
S = StringIO.new("abc")
o = Object.new
class << o; def to_s() S.string = nil; "abc" end end
S.write o'
-e:5: [BUG] Segmentation fault
ruby 1.9.0 (2005-08-13) [i686-linux]

% ./ruby -rstringio -e '
S = StringIO.new("abc")
o = Object.new
class << o; def to_int() S.string = nil; 0 end end
S.putc o'
-e:5: [BUG] Segmentation fault
ruby 1.9.0 (2005-08-13) [i686-linux]

% ./ruby -rstringio -e '
S = StringIO.new("abc")
o = Object.new
class << o; def to_int() S.string = nil; 10 end end
S.read o'
-e:5: [BUG] Segmentation fault
ruby 1.9.0 (2005-08-13) [i686-linux]

まぁ、nil かどうかを必ず検査するようにしてもいいわけですが。

お名前:
E-mail:
コメント:

投稿する前にチェックボックスをチェックしてください

本日のPingbacks(全0件)
本日のリンク元
アンテナ
その他のリンク元
検索

Key fingerprint = 1E69 3ED2 C05B 6BA4 34B2 FC25 478B C08D 2772 58F6