Feature #6643

io.seek(off, :end)

Added by Akira Tanaka almost 2 years ago. Updated about 1 year ago.

[ruby-dev:45818]
Status:Closed
Priority:Normal
Assignee:Akira Tanaka
Category:-
Target version:next minor

Description

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

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

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

思い立ったきっかけとしては、
ひさしぶりに seek を使ったら、
io.seek(IO::SEEKEND)
と書いてしまって、これは私の環境では 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
というふたつの例が見つかります。

どうでしょうか。

io-seek-whence-symbol.patch Magnifier (3.53 KB) Akira Tanaka, 06/25/2012 07:31 PM

patch.diff Magnifier (3.36 KB) Masaki Matsushita, 10/16/2012 09:36 PM

patch2.diff Magnifier (4.44 KB) Masaki Matsushita, 10/22/2012 11:08 AM

patch3.diff Magnifier (4.55 KB) Masaki Matsushita, 11/11/2012 11:15 PM

Associated revisions

Revision 40084
Added by Akira Tanaka about 1 year ago

  • io.c (rbioseekm): Accept :CUR, :END, :SET as "whence" argument. (interpretseek_whence): New function. [Feature #6643]

History

#1 Updated by Motohiro KOSAKI almost 2 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::SEEKEND と等価な指定として :end,
IO::SEEK
CUR と等価な指定として :cur,
IO::SEEK_SET と等価な指定として :set を

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

#2 Updated by Koichi Sasada almost 2 years ago

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

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

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

--
// SASADA Koichi at atdot dot net

#3 Updated by Fumiyasu SATOH almost 2 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::SEEKEND と等価な指定として :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/

#4 Updated by Akira Tanaka almost 2 years ago

2012年6月25日 23:31 SASADA Koichi ko1@atdot.net:

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

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

値に興味を持つ奇特な人がいるかもしれないと頭をよぎっただけですが。
--
[田中 哲][たなか あきら][Tanaka Akira]

#5 Updated by Akira Tanaka almost 2 years ago

2012年6月25日 23:37 SATOH Fumiyasu fumiyas@osstech.jp:

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

:current がよいと思います。

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

あるいは、:cur と :current の両方受け付けるとするか。
--
[田中 哲][たなか あきら][Tanaka Akira]

#6 Updated by Kouhei Sutou almost 2 years ago

須藤です。

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

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

:current がよいと思います。

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

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

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

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

#7 Updated by Kazuhiro NISHIYAMA almost 2 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)

#8 Updated by Akira Tanaka almost 2 years ago

2012年6月26日 22:56 Kazuhiro NISHIYAMA zn@mbf.nifty.com:

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

あぁ、たしかに。大文字がいいかなぁ。
--
[田中 哲][たなか あきら][Tanaka Akira]

#9 Updated by Motohiro KOSAKI almost 2 years ago

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

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

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

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

#10 Updated by Usaku NAKAMURA almost 2 years ago

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

In message " Re: [ruby-trunk - Feature #6643][Open] io.seek(off, :end)"
on Jun.28,2012 03:51:25, kosaki.motohiro@gmail.com 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 usa@garbagecollect.jp
ひつまぶし、じゃなかった、ひまつぶし

#11 Updated by Kazuhiro NISHIYAMA almost 2 years ago

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

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

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

#12 Updated by Koichi Sasada almost 2 years ago

  • Status changed from Open to Assigned
  • Assignee set to Akira Tanaka

#13 Updated by Masaki Matsushita over 1 year ago

こんにちは。

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

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

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

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

#14 Updated by Masaki Matsushita over 1 year ago

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

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

#15 Updated by Kouhei Sutou over 1 year ago

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

#16 Updated by Masaki Matsushita over 1 year ago

Kouhei Sutou wrote:

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

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

#17 Updated by Kouhei Sutou over 1 year ago

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

#18 Updated by Masaki Matsushita over 1 year ago

Kouhei Sutou wrote:

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

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

#19 Updated by Kouhei Sutou over 1 year ago

ありがとうございます!

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

#20 Updated by Koichi Sasada over 1 year ago

  • Target version set to 2.0.0

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

#21 Updated by Akira Tanaka over 1 year ago

2012年10月30日 8:47 ko1 (Koichi Sasada) redmine@ruby-lang.org:

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::SEEKEND) と書いても失敗になるという
利点はあるのですが、激しいなぁ。
--
[田中 哲][たなか あきら][Tanaka Akira]

#22 Updated by Masaki Matsushita over 1 year ago

Akira Tanaka wrote:

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

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

#23 Updated by Masaki Matsushita over 1 year ago

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

#24 Updated by Akira Tanaka over 1 year ago

2012年10月31日 22:23 Glass_saga (Masaki Matsushita) glass.saga@gmail.com:

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]

#25 Updated by Masaki Matsushita over 1 year ago

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

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

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

#26 Updated by Akinori MUSHA over 1 year ago

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

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

#27 Updated by Masaki Matsushita over 1 year ago

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

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

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

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

#28 Updated by Yusuke Endoh over 1 year ago

  • Target version changed from 2.0.0 to next minor

#29 Updated by Akira Tanaka about 1 year 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 (rbioseekm): Accept :CUR, :END, :SET as "whence" argument. (interpretseek_whence): New function. [Feature #6643]

#30 Updated by Akira Tanaka about 1 year ago

2012年11月24日 10:35 mame (Yusuke Endoh) mame@tsg.ne.jp:

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]

Also available in: Atom PDF