Ruby 4.1 リファレンスマニュアル

class IO::Buffer::Storage

[edit]

要約

メモリ領域を管理する IO::Buffer です。 Ruby 4.1 で導入されました。

IO::Buffer.new・IO::Buffer.for・IO::Buffer.map が返すのは、このクラスのインスタンスです。管理するメモリ領域は、Ruby が確保した内部(internal)のもの、仮想メモリ機構でマップされたもの、String など他のオブジェクトから借りた外部(external)のもののいずれかです。

バイト単位の読み書きなどの基本的な操作は、IO::Buffer と共通です。このクラスに固有なのは、メモリ領域の確保と解放に関する次のメソッドです。

このクラスのインスタンスが、必ずメモリ領域を所有しているわけではありません。 IO::Buffer.for で作った外部バッファも、このクラスのインスタンスです。

IO::Buffer::Storage#dup と IO::Buffer::Storage#clone は、バイトをコピーして独立した IO::Buffer::Storage を作ります。別のバッファの一部を参照する IO::Buffer::Slice とは、この点が異なります。

buf = IO::Buffer.new(8)
p buf.class             # => IO::Buffer::Storage

# dup で作った複製は、元のバッファとは独立している
copy = buf.dup
copy.set_string("Ruby")
p copy.get_string(0, 4) # => "Ruby"
p buf.get_string(0, 4)  # => "\x00\x00\x00\x00"

[SEE_ALSO] IO::Buffer, IO::Buffer::Slice

目次

インスタンスメソッド

継承しているメソッド

IO::Bufferから継承している特異メソッド
IO::Bufferから継承しているメソッド
Comparableから継承しているメソッド

インスタンスメソッド

dup -> IO::Buffer::StorageRuby 4.1 から[permalink][rdoc][edit]
clone -> IO::Buffer::Storage

バッファの内容を、独立した内部バッファにコピーして返します。

複製への変更は元のバッファに影響せず、元のバッファへの変更も複製に影響しません。元のバッファが外部バッファや読み取り専用でも、複製は内部バッファで、書き込みできます。

buf = IO::Buffer.for("abc")
p buf.external?  # => true
p buf.readonly?  # => true

copy = buf.dup
p copy.internal? # => true
p copy.readonly? # => false
p copy.source    # => nil

[SEE_ALSO] IO::Buffer::Slice#dup

external? -> boolRuby 4.1 から[permalink][rdoc][edit]

バッファが外部(external)バッファである場合に true を返します。

外部バッファは、バッファ自身が確保・マップしたのではないメモリ領域を参照します。 IO::Buffer.for で作ったバッファは、文字列のメモリを外部参照します。外部バッファは大きさを変更できません。

p IO::Buffer.for("test").external? # => true
p IO::Buffer.new(4).external?      # => false

[SEE_ALSO] IO::Buffer::Storage#internal?

free -> selfRuby 4.1 から[permalink][rdoc][edit]

バッファが確保しているメモリ領域を解放します。

解放の内容はバッファの種類によって異なります。

  • 内部(internal) -- 確保したメモリを解放します。
  • 外部(external) -- 元のオブジェクトとの関連を解消します。
  • マップ(mapped) -- マッピングを解除します。

解放後は、どのメモリ領域も指さない状態になります。この状態のバッファは大きさ 0 のバッファとして扱われます。

解放したバッファでも IO::Buffer::Storage#resize を呼べば、あらためてメモリ領域を確保できます。

IO::Buffer::Slice には、このメソッドはありません。

[EXCEPTION] FrozenError:
凍結済みのバッファに対して呼び出した場合に発生します。
[EXCEPTION] IO::Buffer::LockedError:
ロックされているバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(4)
buf.set_string("Ruby")

buf.free
p buf.null? # => true
p buf.size  # => 0

# resize すれば再び使える
buf.resize(4)
p buf.size  # => 4

[SEE_ALSO] IO::Buffer::Storage#transfer, IO::Buffer#null?

internal? -> boolRuby 4.1 から[permalink][rdoc][edit]

バッファが内部(internal)バッファである場合に true を返します。

内部バッファは、バッファ自身が確保したメモリ領域を参照します。文字列などの外部のメモリやファイルのマッピングとは結び付いていません。 IO::Buffer.new で作られるバッファは既定で内部バッファです。

p IO::Buffer.new(4).internal? # => true

[SEE_ALSO] IO::Buffer::Storage#external?

mapped? -> boolRuby 4.1 から[permalink][rdoc][edit]

バッファがマップ(mapped)バッファである場合に true を返します。

マップバッファは、仮想メモリ機構でマップされたメモリ領域を参照します。 IO::Buffer.new に IO::Buffer::MAPPED を指定した場合や、大きさが IO::Buffer::PAGE_SIZE 以上の場合は匿名のマップになります。 IO::Buffer.map で作った場合はファイルに紐づいたマップになります。

private? -> boolRuby 4.1 から[permalink][rdoc][edit]

バッファがプライベート(private)バッファである場合に true を返します。

プライベートバッファに加えた変更は、元になったファイルのマッピングには反映されません。

resize(size) -> selfRuby 4.1 から[permalink][rdoc][edit]

バッファの大きさを size バイトに変更します。

変更前の内容は保持されます。変更後の大きさによっては、メモリ領域が別の場所に確保しなおされ、内容がそこへコピーされます。

IO::Buffer.for で作った外部バッファや、ロックされたバッファは大きさを変更できません。 IO::Buffer::Slice の大きさは、IO::Buffer::Slice#resize で変更します。

[PARAM] size:
変更後の大きさをバイト数で指定します。
[EXCEPTION] IO::Buffer::AccessError:
大きさを変更できないバッファに対して呼び出した場合に発生します。
[EXCEPTION] FrozenError:
凍結済みのバッファに対して呼び出した場合に発生します。
[EXCEPTION] IO::Buffer::LockedError:
ロックされているバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(4)
buf.set_string("test")

buf.resize(8)
p buf.size             # => 8
p buf.get_string(0, 4) # => "test"

IO::Buffer.for("abc").resize(8) # ~> IO::Buffer::AccessError

[SEE_ALSO] IO::Buffer::Slice#resize

shared? -> boolRuby 4.1 から[permalink][rdoc][edit]

バッファが共有(shared)バッファである場合に true を返します。

共有バッファは、他のプロセスと共有できるメモリ領域を参照します。そのため、このプロセスで変更しなくても内容が変わることがあります。

transfer -> IO::Buffer::StorageRuby 4.1 から[permalink][rdoc][edit]

メモリ領域の所有権を新しい IO::Buffer::Storage へ移し、その新しいバッファを返します。

所有権を手放した自身は、どのメモリ領域も指さない状態になります。この状態は IO::Buffer#null? で調べられます。自身から IO::Buffer#slice で作った IO::Buffer::Slice は、無効になります。

IO::Buffer::Slice には、このメソッドはありません。

[EXCEPTION] FrozenError:
凍結済みのバッファに対して呼び出した場合に発生します。
[EXCEPTION] IO::Buffer::LockedError:
ロックされているバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(4)
buf.set_string("Ruby")

other = buf.transfer
p other.get_string # => "Ruby"

p buf.null? # => true
p buf.size  # => 0

[SEE_ALSO] IO::Buffer::Storage#free, IO::Buffer#null?