要約
別の IO::Buffer の一部を参照する IO::Buffer です。 Ruby 4.1 で導入されました。
IO::Buffer#slice か IO::Buffer::Slice.new で作ります。バイトのコピーはせず、参照元(source)への参照を保持します。参照元は IO::Buffer#source で取得できます。スライスからさらにスライスを作った場合の参照元は、平坦化されずに直接の親になります。
スライスは、参照範囲が参照元の範囲に収まっている間だけ有効です。参照元が IO::Buffer::Storage#free や IO::Buffer::Storage#transfer で手放されたときや、縮小されて参照範囲が外に出たときは、無効になります。無効なスライスの内容を読み出そうとすると IO::Buffer::InvalidatedError が発生します。無効かどうかは IO::Buffer#valid? で調べられます。
参照範囲が再び参照元の範囲内に収まれば、有効に戻ります。参照元のメモリ領域が別のアドレスに再確保されても、無効にはなりません。無効なスライスでも、IO::Buffer#source は参照元を返します。
書き込みは参照元のメモリに反映されます。読み取り専用かどうかなどの権限は、参照元に従います。読み取り専用のバッファのスライスに書き込もうとすると、IO::Buffer::AccessError が発生します。
参照元がロックされている間は、スライスの IO::Buffer#locked? も true になります。スライスを IO::Buffer#locked でロックすると、メモリ領域全体がロックされ、参照元の IO::Buffer::Storage#resize は IO::Buffer::LockedError になります。ロック中でも、スライスの IO::Buffer::Slice#resize と IO::Buffer#advance は呼べます。
IO::Buffer::Slice#resize と IO::Buffer#advance は、見える範囲を変えるだけです。メモリ領域の確保・解放・コピーは行いません。
メモリ領域の確保と解放に関するメソッドは、このクラスにはありません。 IO::Buffer::Storage#free・IO::Buffer::Storage#transfer と、IO::Buffer::Storage#mapped?・IO::Buffer::Storage#external?・IO::Buffer::Storage#internal?・IO::Buffer::Storage#shared?・IO::Buffer::Storage#private? を呼ぶと、NoMethodError が発生します。また IO::Buffer.for・IO::Buffer.map・IO::Buffer.string も、このクラスでは未定義です。
IO::Buffer::Slice#dup と IO::Buffer::Slice#clone は、ビューをコピーします。バイトはコピーされません。複製は元と同じ参照元・位置・大きさを持ち、どちらから書き込んでも同じメモリに書かれます。
buf = IO::Buffer.for("abcdef")
parent = buf.slice(1, 4)
child = parent.slice(1, 2)
p child.source.equal?(parent) # => true
p parent.source.equal?(buf) # => true
p child.get_string # => "cd"
# 親のスライスを進めると、子のスライスの見える範囲もずれる
parent.advance(1)
p child.get_string # => "de"
[SEE_ALSO] IO::Buffer, IO::Buffer::Storage, IO::Buffer#slice
目次
継承しているメソッド
- IO::Bufferから継承している特異メソッド
- IO::Bufferから継承しているメソッド
- Comparableから継承しているメソッド
特異メソッド
new(source, offset = 0, length = nil) -> IO::Buffer::SliceRuby 4.1 から[permalink][rdoc][edit]-
sourceの一部を参照するスライスを作って返します。バイトのコピーはせず、
sourceへの参照を保持します。offsetとlengthを省略すると、source全体を参照します。lengthだけを省略すると、offsetから末尾までを参照します。- [PARAM]
source: - 参照元を IO::Buffer で指定します。IO::Buffer::Storage でも IO::Buffer::Slice でも指定できます。
- [PARAM]
offset: -
参照を開始する位置を、
sourceの先頭からのバイト数で指定します。 - [PARAM]
length: -
参照するバイト数を指定します。省略すると、
offsetから末尾までになります。 - [EXCEPTION]
ArgumentError: -
引数を渡さなかった場合、
offsetやlengthが負の場合、offsetがsourceの大きさを超える場合、またはoffsetとlengthの合計がsourceの大きさを超える場合に発生します。 - [EXCEPTION]
TypeError: -
sourceが IO::Buffer でない場合に発生します。
buf = IO::Buffer.for("abcdefgh") p IO::Buffer::Slice.new(buf, 2, 4).get_string # => "cdef" p IO::Buffer::Slice.new(buf, 2).get_string # => "cdefgh" p IO::Buffer::Slice.new(buf).get_string # => "abcdefgh" # offset が source の大きさと同じ場合は、大きさ 0 のスライスになる p IO::Buffer::Slice.new(buf, 8).size # => 0 IO::Buffer::Slice.new(buf, 9) # ~> ArgumentError IO::Buffer::Slice.new(buf, 6, 4) # ~> ArgumentError IO::Buffer::Slice.new("abc") # ~> TypeError[SEE_ALSO] IO::Buffer#slice
- [PARAM]
インスタンスメソッド
dup -> IO::Buffer::SliceRuby 4.1 から[permalink][rdoc][edit]clone -> IO::Buffer::Slice-
スライスのビューをコピーして返します。
バイトはコピーしません。複製は元と同じ参照元・位置・大きさを持ちます。複製に対する IO::Buffer#advance や IO::Buffer::Slice#resize は、元のスライスのビューに影響しません。どちらから書き込んでも、同じメモリに書かれます。
凍結済みのスライスに対しては、
dupの結果は凍結されず、cloneの結果は凍結されます。buf = IO::Buffer.for("abcdef").dup slice = buf.slice(1, 3) # 複製の advance は、元のスライスのビューに影響しない copy = slice.dup copy.advance(1) p copy.get_string # => "cd" p slice.get_string # => "bcd" # どちらから書き込んでも、同じメモリに書かれる other = slice.dup other.set_string("XY") p buf.get_string # => "aXYdef"[SEE_ALSO] IO::Buffer::Storage#dup
resize(size) -> selfRuby 4.1 から[permalink][rdoc][edit]-
スライスの大きさを
sizeバイトに変更します。参照元の範囲内で、見える範囲の大きさを変えるだけです。メモリ領域の確保・解放・コピーは行わず、参照元も変更されません。大きくした場合は、参照元にある既存のバイトが見えるようになります。クリアはされません。入れ子のスライスでは、直接の親の範囲が上限になります。
参照元がロックされていても呼べます。
Ruby 4.0 までは、スライスも IO::Buffer のインスタンスで、その
resizeは新しいメモリ領域を確保して内容をコピーし、参照元から切り離していました。- [PARAM]
size: - 変更後の大きさをバイト数で指定します。
- [EXCEPTION]
ArgumentError: -
sizeが負の場合や、参照元の範囲を超える場合に発生します。無効になったスライスに対して呼び出した場合も、範囲外として扱われて発生します。 - [EXCEPTION]
FrozenError: - 凍結済みのスライスに対して呼び出した場合に発生します。
buf = IO::Buffer.new(8) buf.set_string("abcdefgh") part = buf.slice(2, 4) p part.get_string # => "cdef" part.resize(2) p part.size # => 2 p part.get_string # => "cd" part.resize(6) p part.get_string # => "cdefgh" part.resize(7) # ~> ArgumentError[SEE_ALSO] IO::Buffer#advance, IO::Buffer::Storage#resize
- [PARAM]