7
>> a = 5
=> 5
>> b = "hello, world!"
=> "hello, world!"
>> b.dup
=> "hello, world!"
>> a.dup
TypeError: can't dup Fixnum
    from (irb):4:in `dup'
    from (irb):4

整数を新しい変数に代入するたびにRubyがコピーを作成することは理解していますが、なぜNumeric#dupエラーが発生するのですか?

すべてのオブジェクトが適切に応答する必要があるため、これは抽象化を壊しません.dupか?

dup私が知る限り、メソッドを書き直すと問題が解決します。

>> class Numeric
>>   def dup()
>>     self
>>   end
>> end

これには、私が見ていない欠点がありますか? これがRubyに組み込まれていないのはなぜですか?

4

2 に答える 2

15

Ruby のほとんどのオブジェクトは参照渡しであり、複製することができます。例えば:

s = "Hello"
t = s      # s & t reference to the same string
t.upcase!  # modifying either one will affect the other
s # ==> "HELLO"

ただし、Ruby のいくつかのオブジェクトは即時です。それらは値によって渡されます。この値は 1 つしか存在できないため、複製することはできません。これらは任意の (小さい) 整数、、、true記号false、およびnilです。64 ビット システムの Ruby 2.0 では、多くの浮動小数点数も即値です。

この (ばかげた) 例では、どの "42" も同じインスタンス変数を保持します。

class Fixnum
  attr_accessor :name
  alias_method :original_to_s, :to_s
  def to_s
    name || original_to_s
  end
end
42.name = "The Answer"
puts *41..43  # =>  41, The Answer, 43

something.dup.name = "new name"通常、 で取得したコピー以外のオブジェクトには影響を与えないと予想されるためdup、Ruby はdup即値を定義しないことを選択します。

あなたの質問は見た目よりも複雑です。これをどのように簡単にできるかについて、ruby-coreに関するいくつかの議論がありました。また、他のタイプの Numeric オブジェクト (float、bignum、有理数、および複素数) は、即値ではありませんが、複製できません。

ActiveSupport (レールの一部) はduplicable?すべてのオブジェクトにメソッドを提供することに注意してください

于 2009-12-26T20:12:46.517 に答える
3

dup()定義した関数の問題は、オブジェクトのコピーを返さず、オブジェクト自体を返すことです。これは、duplicate手順が行うべきことではありません。

私はRubyを知りませんが、dup数値に対して定義されていない理由として考えられるのは、数値が基本型であるため、次のようにすることです。

>> a = 5
>> b = a

メモリ内の同じ値を作成してポイントするのではなく5、変数に値を自動的に割り当てます。bba

于 2009-12-26T19:35:44.780 に答える