IO::Buffer: 状態問い合わせの 10 メソッドを追加#3305
Conversation
empty? / null? / valid? / internal? / external? / readonly? / mapped? / locked? / shared? / private? を追加した。 登場バージョンを実機で確認したところ、8 個は IO::Buffer が導入された 3.1 から あるが、shared? は 3.2、private? は 3.3 からで、それぞれ #@SInCE で分岐した。 readonly? の説明は実機に合わせた。rdoc には「Frozen strings and read-only files create read-only buffers.」とあるが、IO::Buffer.for は凍結していない 文字列から作っても読み取り専用のバッファになる (3.1〜4.0 で確認)。 ブロックを渡した場合のみ書き込み可能になる。 例に使ったコードは 3.1 / 3.2 / 3.3 / 4.0 で実行し、すべて同じ出力になることを 確認している。valid? / mapped? / locked? / shared? / private? は、簡潔で 安定した例を作るのが難しいため、説明のみとした。 bitclust のデータベース生成を 3.1 / 3.2 / 3.3 / 4.0 で実行してエラーが出ないこと、 登録されるメソッドが 8 / 9 / 10 / 10 件と追加バージョンどおりになることを確認済み。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
レビューしました。since 版・挙動はすべて実測どおりで、1 点だけ確認いただきたい点があります(リンク切れ)。 検証(実機 3.1.7 / 3.2.11 / 3.3.12 / 4.0.6 + bitclust ミニ描画)
確認いただきたい点:
|
リンク切れの指摘への対応。IO::Buffer は段階的に追加している途中なので、 未収録のものは収録する回までコードスパンにし、#@# コメントを残した。 - IO::Buffer#set_value / IO::Buffer.map (指摘のあった2件) - IO::Buffer.for (4箇所。うち2箇所は rurema#3301 由来) - IO::Buffer#locked (rurema#3295 由来)。LOCKED 定数の説明が 「[m:IO::Buffer#locked] を参照してください」だけだったので、 本 PR で追加する locked? で調べられる旨の説明に書き換えた - Fiber::Scheduler (rurema#3278 由来) は rdoc へのリンクにした (rurema#3299 と同じ扱い) あわせて、参考として指摘のあった IO::Buffer.new の説明を 「PAGE_SIZE より大きい場合」から「PAGE_SIZE 以上の場合」に修正した。 io_buffer.c は size >= RUBY_IO_BUFFER_PAGE_SIZE で判定しており、 実機でも 3.1〜4.0 のすべてで size == PAGE_SIZE のとき mapped? が true になる。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
レビューありがとうございます。ご指摘の 2 点とも対応しました。 リンク切れ: 収録するまで平文にしました
あわせて全参照を機械的に突き合わせたところ、ご指摘の 2 つ以外にも
突き合わせは、4.0 の DB に対して 参考でご指摘の PAGE_SIZE の境界こちらも同じファイルなので、この PR で直しました。
if (size >= RUBY_IO_BUFFER_PAGE_SIZE) {実機でも $ ruby -e 'ps = IO::Buffer::PAGE_SIZE; p [IO::Buffer.new(ps - 1).mapped?, IO::Buffer.new(ps).mapped?]'
[false, true]3.1.6 / 3.2.11 / 3.3.12 / 3.4.10 / 4.0.6 のすべてで同じ結果でした。 別 PR に分けたほうがよければ、そのように直します。 🤖 Generated with Claude Code |
ruby/ruby#18062 (マージ済み) で IO::Buffer#readonly? の rdoc が明確化された のに合わせる。従来の記述は「IO::Buffer.for で作ったバッファ」とだけ書いており、 ブロックを渡した場合に読み取り専用にならない点が抜けていた。 実機 (3.1.6 / 3.2.11 / 3.4.10 / 4.0.6 で同じ) の挙動: IO::Buffer.for("test").readonly? # => true IO::Buffer.for("test") { |buf| buf.readonly? } # => false IO::Buffer.for("test".freeze) { |buf| buf.readonly? } # => true IO::Buffer.new(4).readonly? # => false ブロックなしの場合は内部で作った文字列の複製を元にするため、元の文字列が freeze されていなくても常に読み取り専用になる。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
レビュー中に恐縮ですが、 経緯
となっていて、 従来の記述は「 実機の挙動 (3.1.6 / 3.2.11 / 3.4.10 / 4.0.6 で同じ)$ ruby -e 'p IO::Buffer.for("test").readonly?'
true
$ ruby -e 'p(IO::Buffer.for("test") { |buf| buf.readonly? })'
false
$ ruby -e 'p(IO::Buffer.for("test".freeze) { |buf| buf.readonly? })'
true
$ ruby -e 'p IO::Buffer.new(4).readonly?'
falseブロックなしの場合は内部で作った文字列の複製をバッファの元として使うため 記述はこの区別を説明する形に書き直し、例も 3 ケース (ブロックなし /
🤖 Generated with Claude Code |
|
対応ありがとうございます。2 点とも確認しました。
4.0 で statichtml をビルドして compileerror 0 を確認済みです。マージ可と考えます。 🤖 Generated with Claude Code |
IO::Buffer.for / IO::Buffer.map / IO::Buffer.string を追加した。 IO::Buffer.string は 3.3 で追加されたため #@SInCE 3.3 で分岐する。 実機で確認した挙動: - for はブロックを渡さない場合、内容を複製した凍結済みの文字列を元にするため、 あとから元の文字列を変更してもバッファは変わらない。 - for にブロックを渡した場合は元の文字列自身を参照し、ブロックの実行中は 元の文字列を変更できない (RuntimeError)。 - map は既定で書き込み可能かつ共有のマップになるため、読み込み専用で開いた ファイルをそのまま渡すと Errno::EACCES になる。 - offset はシステム依存で、多くの環境ではページサイズの倍数である必要がある。 あわせて以下を修正した。 - #3305 で平文にしていた IO::Buffer.for / IO::Buffer.map への参照をリンクに戻した。 - PAGE_SIZE 定数の説明が「size がこの値より大きい場合」のままだった。 #3305 で IO::Buffer.new 側は「以上」に直したが、定数側が残っていた。 - get_string の例の期待値 #<Encoding:BINARY (ASCII-8BIT)> は 3.4 以降の表示で、 3.1〜3.3 では #<Encoding:ASCII-8BIT> になる。.encoding.name に変えて 全版で一致するようにした。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
概要
[c:IO::Buffer] の状態を問い合わせる 10 メソッドを追加しました。
#3278 / #3295 / #3301 の続きです。
empty?/null?/valid?/internal?/external?/readonly?/mapped?/locked?/shared?/private?レビューを受けて、同じファイル内のリンク切れの解消と、
IO::Buffer.newの説明の誤り (1 バイトのずれ) の修正も含んでいます。
登場バージョン
実機で確認したところ、8 個は
IO::Bufferが導入された Ruby 3.1 からありますが、2 個は後の版で追加されていました。
#@sinceで分岐しています。shared?… 3.2 からprivate?… 3.3 からreadonly? は Ruby 本体の rdoc も直しました
rdoc には「Frozen strings and read-only files create read-only buffers.」と
だけ書かれていましたが、
IO::Buffer.forにブロックを渡さない場合は、元の文字列が freeze されていなくても常に読み取り専用になります。これが一番よく
あるケースなのに説明が抜けていたため、Ruby 本体にも修正を送り、
ruby/ruby#18062 としてマージされました。
るりま側もこの区別を説明する形にしています (3.1.6 / 3.2.11 / 3.4.10 / 4.0.6 で
同じ挙動を確認)。
ブロックなしの場合は内部で作った文字列の複製をバッファの元として使うため
(
rb_io_buffer_type_forがその経路でRB_IO_BUFFER_READONLYを無条件に渡す)、元の文字列が freeze されているかどうかによらず読み取り専用になります。
未収録 API へのリンクは平文にしました (レビュー対応)
IO::Bufferは段階的に追加している途中で、まだ収録していないメソッドを参照している箇所がありました。リンクにすると存在しない URL を指してしまうため、
収録する回まではコードスパンにし、戻し忘れないよう
#@#コメントを添えています。IO::Buffer#set_valueIO::Buffer.mapIO::Buffer.forIO::Buffer#lockedlocked?への案内に書き換えた (#3295 由来)Fiber::SchedulerIO::Buffer.new の PAGE_SIZE の境界を修正しました (レビュー対応)
IO::Buffer.newの説明が「size がPAGE_SIZEより大きい場合」となっていましたが、実装は
>=です。3.1.6 / 3.2.11 / 3.3.12 / 3.4.10 / 4.0.6 のいずれも同じ結果で、「
PAGE_SIZE以上の場合」に修正しました。
例について
例に使ったコードは 3.1 / 3.2 / 3.3 / 4.0 で実行し、すべて同じ出力になることを
確認しました。
valid?/mapped?/locked?/shared?/private?は、簡潔で安定した例を作るのが難しい(ファイルのマッピングや slice の無効化などが必要になる)ため、
説明のみとしています。
検証
rake check_format/check_blank_lines/check_indent_in_samplecode/check_single_space_indentbitclust update --markdowntree=manual/apiを 3.1 / 3.2 / 3.3 / 4.0 で実行し、エラーが出ないこと、登録されるメソッドが 8 / 9 / 10 / 10 件と
上記の追加バージョンどおりになることを確認しました。
IO__Buffer.md由来の全エントリについて[m:...]/[c:...]を DB と突き合わせ、リンク切れが 0 件であることを確認しました。
🤖 Generated with Claude Code