Project

General

Profile

Actions

Feature #6643

closed

io.seek(off, :end)

Added by akr (Akira Tanaka) almost 12 years ago. Updated about 11 years ago.

Status:
Closed
Target version:
[ruby-dev:45818]

Description

IO#seek メソッドの whence 引数としてシンボルを受け付けるようにしませんか。

つまり、
io.seek(0, IO::SEEK_END)
のかわりに
io.seek(0, :end)
とかけるようにする、ということです。

IO::SEEK_END と等価な指定として :end,
IO::SEEK_CUR と等価な指定として :cur,
IO::SEEK_SET と等価な指定として :set を
受け付けるようにします。

思い立ったきっかけとしては、
ひさしぶりに seek を使ったら、
io.seek(IO::SEEK_END)
と書いてしまって、これは私の環境では IO::SEEK_END が 2 なので、
io.seek(2)
つまり
io.seek(2, IO::SEEK_SET)
と解釈されてしまって、ちょっと悩んだためです。

もし同様な間違いをしてしまっても、IO::SEEK_END でなく :end と
書いたのであれば、
io.seek(:end)
は can't convert Symbol into Integer (TypeError) となるので悩まなくて済んだのに、
と思いました。

なお、その間違いをしたのは私だけではないようで、検索すると
http://jira.codehaus.org/browse/JRUBY-1897
http://rubyforge.org/pipermail/biocatalogue-developers/attachments/20100512/2eacb73c/attachment-0001.html
というふたつの例が見つかります。

どうでしょうか。


Files

io-seek-whence-symbol.patch (3.53 KB) io-seek-whence-symbol.patch akr (Akira Tanaka), 06/25/2012 07:31 PM
patch.diff (3.36 KB) patch.diff Glass_saga (Masaki Matsushita), 10/16/2012 09:36 PM
patch2.diff (4.44 KB) patch2.diff Glass_saga (Masaki Matsushita), 10/22/2012 11:08 AM
patch3.diff (4.55 KB) patch3.diff Glass_saga (Masaki Matsushita), 11/11/2012 11:15 PM

Updated by kosaki (Motohiro KOSAKI) almost 12 years ago

(6/25/12 6:32 AM), akr (Akira Tanaka) wrote:

Issue #6643 has been reported by akr (Akira Tanaka).


Feature #6643: io.seek(off, :end)
https://bugs.ruby-lang.org/issues/6643

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:

IO#seek メソッドの whence 引数としてシンボルを受け付けるようにしませんか。

つまり、
io.seek(0, IO::SEEK_END)
のかわりに
io.seek(0, :end)
とかけるようにする、ということです。

IO::SEEK_END と等価な指定として :end,
IO::SEEK_CUR と等価な指定として :cur,
IO::SEEK_SET と等価な指定として :set を

+1.
というかIOまわりの定数は全部シンボルで指定したいぐらい。。

Updated by ko1 (Koichi Sasada) almost 12 years ago

(2012/06/25 23:17), KOSAKI Motohiro wrote:

IO::SEEK_END と等価な指定として :end,
IO::SEEK_CUR と等価な指定として :cur,
IO::SEEK_SET と等価な指定として :set を
+1.
というかIOまわりの定数は全部シンボルで指定したいぐらい。。

 これ,例えば IO::SEEK_END も値が :end になるんでしょうか(なっちゃいけ
ない理由はあるんかな).

--
// SASADA Koichi at atdot dot net

Updated by fumiyas (Fumiyasu SATOH) almost 12 years ago

At Mon, 25 Jun 2012 19:32:06 +0900,
akr (Akira Tanaka) wrote:

IO#seek メソッドの whence 引数としてシンボルを受け付けるようにしませんか。

つまり、
io.seek(0, IO::SEEK_END)
のかわりに
io.seek(0, :end)
とかけるようにする、ということです。

IO::SEEK_END と等価な指定として :end,
IO::SEEK_CUR と等価な指定として :cur,

:current がよいと思います。

IO::SEEK_SET と等価な指定として :set を

--
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- GitHub Home: https://GitHub.com/fumiyas/

Updated by akr (Akira Tanaka) almost 12 years ago

2012年6月25日 23:31 SASADA Koichi :

 これ,例えば IO::SEEK_END も値が :end になるんでしょうか(なっちゃいけ
ない理由はあるんかな).

してもいいんですが、今はしていません。

値に興味を持つ奇特な人がいるかもしれないと頭をよぎっただけですが。

[田中 哲][たなか あきら][Tanaka Akira]

Updated by akr (Akira Tanaka) almost 12 years ago

2012年6月25日 23:37 SATOH Fumiyasu :

IO::SEEK_CUR と等価な指定として :cur,

:current がよいと思います。

:current にしても
IO::SEEK_CUR よりも短いからそれでもいいかなぁ。

あるいは、:cur と :current の両方受け付けるとするか。

[田中 哲][たなか あきら][Tanaka Akira]

Updated by kou (Kouhei Sutou) almost 12 years ago

須藤です。

In
"[ruby-dev:45843] Re: [ruby-trunk - Feature #6643][Open] io.seek(off, :end)" on Tue, 26 Jun 2012 05:10:47 +0900,
Tanaka Akira wrote:

IO::SEEK_CUR と等価な指定として :cur,

:current がよいと思います。

:current にしても
IO::SEEK_CUR よりも短いからそれでもいいかなぁ。

あるいは、:cur と :current の両方受け付けるとするか。

両方でもいい気がします。

理由は
:curはCのSEEK_CURから連想する(昔ながらの)人用で、
:currentはSEEK_*を意識しなくても見てすぐわかりたい(最近の)人用
というように(私には)自然な提供理由をつけられるからです。

Updated by znz (Kazuhiro NISHIYAMA) almost 12 years ago

西山和広です。

At Tue, 26 Jun 2012 05:10:47 +0900,
Tanaka Akira wrote:

IO::SEEK_CUR と等価な指定として :cur,

:current がよいと思います。

:current にしても
IO::SEEK_CUR よりも短いからそれでもいいかなぁ。

あるいは、:cur と :current の両方受け付けるとするか。

両方が良いに一票。

それとは別に

ソケットライブラリの改善
http://rubykaigi.org/2009/ja/talks/19M02

から連想すると共通の prefix を省略したシンボルになりそうなので、
大文字の :END や :CUR などになるのかと思ったのですが、
小文字にしたのはなぜでしょうか?

--
|ZnZ(ゼット エヌ ゼット)
|西山和広(Kazuhiro NISHIYAMA)

Updated by akr (Akira Tanaka) almost 12 years ago

2012年6月26日 22:56 Kazuhiro NISHIYAMA :

から連想すると共通の prefix を省略したシンボルになりそうなので、
大文字の :END や :CUR などになるのかと思ったのですが、
小文字にしたのはなぜでしょうか?

あぁ、たしかに。大文字がいいかなぁ。

[田中 哲][たなか あきら][Tanaka Akira]

Updated by kosaki (Motohiro KOSAKI) almost 12 years ago

ソケットライブラリの改善
http://rubykaigi.org/2009/ja/talks/19M02

から連想すると共通の prefix を省略したシンボルになりそうなので、
大文字の :END や :CUR などになるのかと思ったのですが、
小文字にしたのはなぜでしょうか?

Socketの場合は、英単語からは想像しづらい動作をするケースがままあるので
C由来だから、字面を信じずにマニュアルちゃんと読みやがれというニュアンスが
漂っていて、大文字がすごくいい感じだったのですが、こちらはどうなんでしょうね。 大文字で :CURRENT ってくどくないです?
C由来ちっくな名前にするなら CURだけでいいような気がするなあ

bikeshedってどうしてこうも人をひきつけるのか

Updated by usa (Usaku NAKAMURA) almost 12 years ago

こんにちは、なかむら(う)です。

In message "[ruby-dev:45864] Re: [ruby-trunk - Feature #6643][Open] io.seek(off, :end)"
on Jun.28,2012 03:51:25, wrote:

Socketの場合は、英単語からは想像しづらい動作をするケースがままあるので
C由来だから、字面を信じずにマニュアルちゃんと読みやがれというニュアンスが
漂っていて、大文字がすごくいい感じだったのですが、こちらはどうなんでしょうね。 大文字で :CURRENT ってくどくないです?
C由来ちっくな名前にするなら CURだけでいいような気がするなあ

こういう時は慌てず騒がず他の言語の例をですね...

C++: std::iosのbeg, cur, end
SEEK_SETがbegになってることが目を引きますね。

.NET: SeekOriginのBegin, Current, End
こっちはフルネーム。やっぱりSEEK_SETはBeginになります。

他にも調べたんですが、SEEK_SET相当しか提供しないとか、Cの定数
の値(0,1,2)を指定するしかなくて名前が付いてないとか、そんなん
が多かったですね...

bikeshedってどうしてこうも人をひきつけるのか

いやまったく。

それでは。

U.Nakamura
ひつまぶし、じゃなかった、ひまつぶし

Updated by znz (Kazuhiro NISHIYAMA) almost 12 years ago

から連想すると共通の prefix を省略したシンボルになりそうなので、
大文字の :END や :CUR などになるのかと思ったのですが、
小文字にしたのはなぜでしょうか?

あぁ、たしかに。大文字がいいかなぁ。

どちらかだけにしたい理由理由が特にないのなら、大文字も小文字も
両方受け付けるようにすれば良いのではないでしょうか。

Updated by ko1 (Koichi Sasada) almost 12 years ago

  • Status changed from Open to Assigned
  • Assignee set to akr (Akira Tanaka)

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

こんにちは。

(Mon, 25 Jun 2012 23:31:12 +0900), SASADA Koichi wrote:

これ,例えば IO::SEEK_END も値が :end になるんでしょうか(なっちゃいけない理由はあるんかな).

IO::SEEK_XXXの値もSymbolにした上でSymbolを受け付けるIO#seekを作ってみたところ、StringIOで引っかかりました。
ext/stringio/stringio.cのstrio_seek()が、IO::SEEK_XXXはFixnumであるという前提の元に書かれているので、値を変えてしまうと動きません。

これがStringIOだけなら良いのですが、サードパーティの拡張ライブラリにも同様のものがあるかも知れません。

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

IO::SEEK_XXXの値は従来のままとして、whence引数にIntegerもSymbolも受け付けるIO#seekを作ってみました。
Symbolとしては、:set, :cur, :current, :endを大文字小文字を区別せず受け付けます。

これで互換性を崩さずにSymbolも渡せるようになるので良いんじゃないかと思うのですが、いかがでしょうか。

Updated by kou (Kouhei Sutou) over 11 years ago

"type mismatch: %s given"というエラーメッセージに、「本当はIntegerかSymbolで指定して欲しかったんだよ!」みたいな情報が入っていると、間違ったオブジェクトを指定してしまった時にどうすればうまく動くようにできるかがわかりやすくなってうれしいなぁと思いました!

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

Kouhei Sutou wrote:

"type mismatch: %s given"というエラーメッセージに、「本当はIntegerかSymbolで指定して欲しかったんだよ!」みたいな情報が入っていると、間違ったオブジェクトを指定してしまった時にどうすればうまく動くようにできるかがわかりやすくなってうれしいなぁと思いました!

"%s is not an Integer or Symbol"や、"whence must be an Integer or Symbol"が良いでしょうか。

Updated by kou (Kouhei Sutou) over 11 years ago

個人的には(1)間違った値と(2)間違っている理由と(3)期待する値が入ったエラーメッセージがあると直す時に嬉しいので、今ある案がまざった"whence must be an Integer or Symbol: %s given"みたいなのがいいんじゃないかと思います!
(自分が書くときは"whence must be an Integer or Symbol: <%s>"みたいに間違った値を「<>」とかの記号で囲んだりします。空文字列だったときにわかりづらいので。。。)

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

Kouhei Sutou wrote:

個人的には(1)間違った値と(2)間違っている理由と(3)期待する値が入ったエラーメッセージがあると直す時に嬉しいので、今ある案がまざった"whence must be an Integer or Symbol: %s given"みたいなのがいいんじゃないかと思います!

なるほど。確かにその3つの情報が入っていると直す時に嬉しいですね。
エラーメッセージを改善したpatchを添付します。
コメントにも修正を加えています。

Updated by kou (Kouhei Sutou) over 11 years ago

ありがとうございます!

反対している人はいないので、コミットしていいんじゃないかなぁと思います。

Updated by ko1 (Koichi Sasada) over 11 years ago

  • Target version set to 2.0.0

田中さんに一応聞いておきたいところ.

Updated by akr (Akira Tanaka) over 11 years ago

2012年10月30日 8:47 ko1 (Koichi Sasada) :

Issue #6643 has been updated by ko1 (Koichi Sasada).

Target version set to 2.0.0

田中さんに一応聞いておきたいところ.

最新のパッチは確認していないのですが、
IO::SEEK_* の値をシンボルに変えてしまうのはどうなのかなぁ。

StringIO は修正すれば済むわけですが、
StringIO 以外にもだれか他の人が IO もどきを作っている可能性はあって、
そういうものに対する非互換性になりますよねぇ。

IO::SEEK_* を変えると io.seek(IO::SEEK_END) と書いても失敗になるという
利点はあるのですが、激しいなぁ。

[田中 哲][たなか あきら][Tanaka Akira]

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

Akira Tanaka wrote:

StringIO は修正すれば済むわけですが、
StringIO 以外にもだれか他の人が IO もどきを作っている可能性はあって、
そういうものに対する非互換性になりますよねぇ。

そうですね。
最新のパッチ(patch2.diff)では、そういう懸念があるのでIO::SEEK_*の値は変えずにIntegerもSymbolも受け付けるようにしています。

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

patch2.diff(IO::SEEK_*の値は変えないで、新たにSymbolも大文字小文字を無視して受け付けるようにしたpatch)をコミットしたいのですが、反対はありませんか?
しばらく待って反対がなければ、入れてしまおうと思います。

Updated by akr (Akira Tanaka) over 11 years ago

2012年10月31日 22:23 Glass_saga (Masaki Matsushita) :

Issue #6643 has been updated by Glass_saga (Masaki Matsushita).

そうですね。
最新のパッチ(patch2.diff)では、そういう懸念があるのでIO::SEEK_*の値は変えずにIntegerもSymbolも受け付けるようにしています。

すいません。失礼しました。
(redmine が落ちているときにメールを書くのではなかった...)

パッチを見て思ったのですが、:eNd とかまで受け付けているのは、
受け付けすぎではないかなぁ、という気がします。

% ./ruby -ve 'open("NEWS") {|f| f.seek(0, :eNd); p f.pos }'
ruby 2.0.0dev (2012-11-06 trunk 37493) [x86_64-linux]
10175

また、エラーメッセージに出てくるのは、小文字に変換した後のものに
なっていますが、これはエラーメッセージとして正確ではないなぁ、と思いました。

% ./ruby -ve 'open("NEWS") {|f| f.seek(0, :FOO); p f.pos }'
ruby 2.0.0dev (2012-11-06 trunk 37493) [x86_64-linux]
-e:1:in seek': unknown whence: foo (ArgumentError) from -e:1:in block in '
from -e:1:in open' from -e:1:in '
zsh: exit 1 ./ruby -ve 'open("NEWS") {|f| f.seek(0, :FOO); p f.pos }'

[田中 哲][たなか あきら][Tanaka Akira]

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

:setか:SETの類だけ受け付ければ良いのであれば、小文字のシンボルも大文字のシンボルも変数として持っておいて良いんじゃないかなあと思いました。
(あまりスマートではない気もしますが)

:Setや:Currentも使えた方が良い、という人はいませんよね?

なので、そのようにしたpatchをつくりました。
:eNdのようなシンボルまで受け付けてしまう問題、エラーメッセージの正確さの問題はこれで解決します。
また、先のpatchではdowncase!して小文字に合わせていたので、大文字が好みの人にだけメソッド呼び出しのコストを強いていましたが、
両方変数として持っておけばそのような事もありません。

Updated by knu (Akinori MUSHA) over 11 years ago

今さらですが、すべて大文字のシンボルだけサポートすればいいのではないでしょうか。
seekのラッパーとか、IOライクなクラスの実装とかで揺れの許容が期待されるのは重荷になると思います。
こうしたコンベンションを他のメソッドにおける定数にも拡大していくことを考えるとなおさらです。

「Unix/Cの定数マクロをシンボル化する際は、大文字のまま。自明な場合は共通のプレフィックスを除く」というシンプルなルールに沿えば、trapにおけるシグナル名の扱いとも整合しますし、毎度:cur→:currentみたいな略語の展開など余計なことを考えなくて済みます。

Updated by Glass_saga (Masaki Matsushita) over 11 years ago

「Unix/Cの定数マクロをシンボル化する際は、大文字のまま。自明な場合は共通のプレフィックスを除く」というシンプルなルール

IO#adviseはこのルールに沿っていませんね。
例えばPOSIX_FADV_NORMALに対応するRubyのシンボルは:normalです。

一方BasicSocket#setsockoptはこのルールに従っていて、例えばSO_REUSEADDRに対応するシンボルは:REUSEADDRです。

ルールを決めて統一してしまった方が良いのかも知れません。

Updated by mame (Yusuke Endoh) over 11 years ago

  • Target version changed from 2.0.0 to 2.6
Actions #29

Updated by akr (Akira Tanaka) about 11 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r40084.
Akira, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • io.c (rb_io_seek_m): Accept :CUR, :END, :SET as "whence" argument.
    (interpret_seek_whence): New function.
    [ruby-dev:45818] [Feature #6643]

Updated by akr (Akira Tanaka) about 11 years ago

2012年11月24日 10:35 mame (Yusuke Endoh) :

Feature #6643: io.seek(off, :end)
https://bugs.ruby-lang.org/issues/6643#change-33713

IO#seek メソッドの whence 引数としてシンボルを受け付けるようにしませんか。

議論を読み直したのですが、結局、これから意見がまとまるきはしないので、
最小限のものを入れようということで、C プログラマにわかりやすいという理由で、
C と同じ大文字で :CUR, :END, :SET だけ受け付けるとして入れました。

[田中 哲][たなか あきら][Tanaka Akira]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0