6

このプログラム

class ObjectGarden
    class << self.clone
            puts self.object_id
    end
end

puts ObjectGarden.clone.object_id

Linuxで実行すると(RHELでテスト済み)、object_id予想どおり、複数の実行にわたって個別のが生成されます。ただし、Windowsで実行すると、複数回実行しても同じ出力が得られます。そして、私が何をしても(休止/シャットダウン/「悪名高いブルースクリーン」と再起動)、object_idは変わりません。

object_idまた、Windowsの変更では、プログラムのコンテンツを変更した場合(新しい行やコメントを追加するなどの重要でない変更でも)に気付きます。

WindowsとLinuxの実装でこの違いがあるのはなぜですか?そして、私はOS Xにアクセスできないので、誰かがMacでOS Xを実行して、結果を文書化してください。

WindowsではRuby1.9.2-p136を使用し、LinuxではRuby1.9.2-p180を使用しています。

4

1 に答える 1

1

Ruby のほとんどのオブジェクトでは、取得する数値#object_idは、実際にはオブジェクトの内部 C データ構造へのポインターです。このデータ構造には、Ruby の実装/ビルドが使用するメモリ アロケータによって割り当てられた領域があります。

コードを読まなくても、Linux バージョンは毎回異なる結果を生成していると推測できます。これは、Ruby または C アロケーターのいずれかが、意図的に割り当てまたはポインターにランダムなオフセットを使用して、それらを推測しにくくし、プログラムをより複雑にしているためです。安全。

について ruby​​ が保証することは 1 つだけですobject_id: 特定のオブジェクトが存在する限り、そのオブジェクトはそのobject_idruby​​ インタープリターに固有のものであり、変更されません。それで全部です。object_id同じメモリ チャンクを取得することになる場合は、以前に作成され、後でガベージ コレクションされたオブジェクトと同じものを取得することもできます。

また、次のようなことを行う場合は注意してください。

irb(main):001:0> a = "hi"
=> "hi"
irb(main):002:0> a.object_id
=> 14348380
irb(main):003:0> a = a + " there"
=> "hi there"
irb(main):004:0> a.object_id
=> 14197020

この行a = a + " there"は実際には new を使用して新しいオブジェクトを作成しますが、object_idusingはそうで#concatはありません:

irb(main):005:0> a = "hi"
=> "hi"
irb(main):006:0> a.object_id
=> 12031400
irb(main):007:0> a.concat " there"
=> "hi there"
irb(main):008:0> a.object_id
=> 12031400

また、Ruby では、代入は代入された変数をオブジェクトにバインドするため、ある変数を別の変数に代入すると、両方が同じオブジェクトを指すことに注意してください。

irb(main):011:0> a = "hi"
=> "hi"
irb(main):012:0> a.object_id
=> 12081640
irb(main):013:0> b = a
=> "hi"
irb(main):014:0> b.object_id
=> 12081640

したがって、1 つの変数を変更すると、もう 1 つの変数が変更されます。

irb(main):015:0> a.concat " there"
=> "hi there"
irb(main):016:0> b
=> "hi there"
于 2012-12-09T22:18:23.267 に答える