[#24536] 「Rubyの落し方」 v.s. ruby_1_8 — akira yamada / やまだあきら <akira@...>

<URL:http://jp.rubyist.net/magazine/?0002-RubyCore>

40 messages 2004/10/20
[#24541] Re: 「Rubyの落し方」 v.s. ruby_1_8 — Yukihiro Matsumoto <matz@...> 2004/10/20

まつもと ゆきひろです

[#24599] 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/26

2004-10-20 (水) の 21:38 +0900 に Yukihiro Matsumoto さんは書きました:

[#24605] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-26 (火) の 16:16 +0900 に akira yamada / やまだあきら さんは書きました:

[#24606] Re: 1.8.2 preview3? — Yukihiro Matsumoto <matz@...> 2004/10/27

まつもと ゆきひろです

[#24608] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-27 (水) の 11:48 +0900 に Yukihiro Matsumoto さんは書きました:

[#24620] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-27 (水) の 12:42 +0900 に akira yamada / やまだあきら さんは書きました:

[#24629] Re: 1.8.2 preview3? — Tanaka Akira <akr@...17n.org> 2004/10/29

In article <1098888819.9446.14.camel@rice.p.arika.org>,

[ruby-dev:24450] Re: ARGF.read(len) and EOF

From: Tanaka Akira <akr@...17n.org>
Date: 2004-10-08 10:42:31 UTC
List: ruby-dev #24450
In article <1097228154.590547.23205.nullmailer@x31.priv.netlab.jp>,
  Yukihiro Matsumoto <matz@ruby-lang.org> writes:

> まず、readは決してnilを返しません。指定した長さ(または現状入
> 手可能なすべて)ぶんだけ読み込んで返します。EOFに当たると指定
> した長さより短い文字列を返します。
>
> ARGFは引数にファイルが指定されている時には、そのすべてを連結
> した仮想的なファイルとして動作し、その仮想ファイルが(最後の
> ファイルの)EOFに突き当たってからもう一度読もうとすると、今度
> は改めて標準入力から読み込む、という動作になっています。
>
> ですから、最初のARGF.read(4096)で仮想ファイルの全てを読み込
> みEOFに突き当たり、次のARGF.read(4096)では標準入力から読み込
> むのではないかと思います。ループする場合には
>
>   loop do
>     s = ARGF.read(4096)
>     p s
>     break if s.size < 4096
>   end
>
> のようになるのではないかと思います。
>
> これでは使いにくいなどありましたら聞かせてください。

その挙動は IO と異なり、polymorphic でないため、IO を受け取るメソッド
に、ARGF を渡せないという問題が発生します。

たとえば、fileutils に FileUtils.compare_stream というメソッドがありま
す。これに IO を渡すと動くのに、ARGF を渡すと標準入力を待ってしまいます。

% echo aaa > a                                                       
% ruby -rfileutils -e 'p FileUtils.compare_stream(open("a"), open("a"))' 
true
% ruby -rfileutils -e 'p FileUtils.compare_stream(open("a"), ARGF)' a
(標準入力待ち)

一般に read をくりかえし呼ぶとそのうち EOF で nil が返って来る、という
期待をしているライブラリに ARGF を渡すとこういう症状が現われるわけです。

これはおそらくそれなりにある状況で、たとえば、iconv-io もそうです。

% date > aaa
% ruby -riconv/io -e 'p Iconv::Reader.new(open("aaa"), "US-ASCII", "US-ASCII").read'
"Fri Oct  8 19:06:41 JST 2004\n"
% ruby -riconv/io -e 'p Iconv::Reader.new(ARGF, "US-ASCII", "US-ASCII").read' aaa
(標準入力待ち)

そして、今作っている C 言語の字句解析を行なうライブラリでも引っかかり
ました。(それで発見したのですが。)

というわけで、IO が使える所で ARGF が使えないケースがいくつかあるのは
事実で、そのときには使いにくい、というわけです。

EOF を通知した後に標準入力から読み始めるのが根本的な問題だと思うんです
が、これを EOF を通知し続けるようにするのはどうでしょう?

なお、perl の read に ARGV をではちゃんと止まります。

% (date; date) > aaa
% perl -e 'printf "line:[%s]\n", scalar(<>); while(read(ARGV, $buf, 3)) { print "read:[$buf]\n" }' aaa 
line:[Fri Oct  8 19:38:36 JST 2004
]
read:[Fri]
read:[ Oc]
read:[t  ]
read:[8 1]
read:[9:3]
read:[8:3]
read:[6 J]
read:[ST ]
read:[200]
read:[4
]

まぁ、ARGV を設定したりするのは <> なので、
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread