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

module function ObjectSpace?.each_object

each_object {|object| ...} -> Integer[permalink][rdoc][edit]
each_object(klass) {|object| ...} -> Integer
each_object -> Enumerator
each_object(klass) -> Enumerator
(?Module module) → Enumerator[untyped, Integer]
(?Module module) { (untyped obj) → void } → Integer

指定された klass と Object#kind_of? の関係にある全てのオブジェクトに対して繰り返します。引数が省略された時には全てのオブジェクトに対して繰り返します。繰り返した数を返します。

ブロックが与えられなかった場合は、 Enumerator オブジェクトを返します。

次のオブジェクトについては繰り返しません

  • 即値の Integer オブジェクト(ヒープ上に確保される大きな整数は繰り返します)
  • Flonum(即値の Float オブジェクト)
  • 静的な Symbol オブジェクト(動的に生成されたシンボルは繰り返します)
  • TrueClass
  • FalseClass
  • NilClass

なお、Symbol をすべて列挙するには、かわりに Symbol.all_symbols が使用できます。

Ruby 4.1 からオブジェクト空間は Ractor ごとに分かれています。呼び出した Ractor が作成したオブジェクトと、他の Ractor の shareable なオブジェクト(クラスやモジュール、freeze された文字列など)だけを繰り返します。他の Ractor が作成した shareable でないオブジェクトは繰り返しません。

Ruby 4.0 までは、main 以外の Ractor を作成したあとは、どの Ractor から呼び出しても shareable なオブジェクトだけを繰り返していました。

すべての Ractor のオブジェクトを調べたい場合は、objspace の ObjectSpace.dump_all が使えます。

[PARAM] klass:
クラスかモジュールを指定します。
例: ブロックなし
p ObjectSpace.each_object
# => #<Enumerator: ObjectSpace:each_object(false)>
例: 全てのオブジェクトを扱う
ObjectSpace.each_object.take(5).each { |x| p x }
count = ObjectSpace.each_object { |x| x }
puts "Total count: #{count}"

# => "scope"
# => "scopes"
# => "sym"
# => "class_names"
# => "@corrections"
# => Total count: 9938
例: 任意のクラスを扱う
Person = Struct.new(:name)
s1 = Person.new("tanaka")
s2 = Person.new("sato")

count = ObjectSpace.each_object(Person) { |x| p x }
puts "Total count: #{count}"

# => #<struct Person name="sato">
# => #<struct Person name="tanaka">
# => Total count: 2
例: 複数の Ractor がある場合
class Foo; end
objs = 3.times.map { Foo.new }
r = Ractor.new { ObjectSpace.each_object(Foo).count }
p r.value                            # => 0
p ObjectSpace.each_object(Foo).count # => 3
p objs.size                          # => 3