2009-12-26 6 views
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에 올바르게 응답해야하므로이 추상화를 중단하지 않겠습니까?

지금까지 내가 말할 수있는 dup 방법으로 문제가 해결됩니다 다시 쓰기 :

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

이 내가 보이지 않아요 단점이 있습니까? 왜 이것이 Ruby에 내장되어 있지 않습니까?

답변

14

루비의 대부분의 객체는 참조로 전달되며 이중화 될 수 있습니다. 예 :

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

Ruby의 일부 객체는 즉각적으로 사용됩니다. 그들은 가치에 의해 전달되며,이 가치 중 하나만있을 수 있으며, 따라서 그것을 속일 수 없습니다. 이들은 (작은) 정수이고, 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 얻을 복사 이외의 다른 물체에 영향을 미치지 기대 때문에

는, 루비는 immediate 만에 dup을 정의하지 않기로.

질문이 표시되는 것보다 더 복잡합니다. 루비 코어에는 더 쉽게 만들 수있는 방법에 관해서는 some discussion이있었습니다. 또한 다른 유형의 숫자 ​​객체 (수레, bignums, rationals 및 복소수)도 중개하지 않지만 속지 수 없습니다. ActiveSupport (레일의 일부) 모든 객체 루비가 않습니다 정확히 무엇을, 그래서 당신이 숫자 유형 내 방법을 사용할 때, 그것은 새 복사본을 반환합니다

+1

Rails가 아닌 ActiveSupport는 'duplicable?'메소드를 제공합니다.따라서 ActiveSupport를 설치하고 (그리고 다른 많은) 유틸리티 메소드를 원하면 ActiveSupport ('require'active_support'') 만 필요할 수 있습니다. – henrikhodne

+0

사실. 업데이트 됨. –

+0

링크는 https://bugs.ruby-lang.org/issues/1844로 대체해야합니다. 또한 진전이 없었기 때문에이 기능은 거부되었습니다. –

2

정의한 dup() 함수의 문제점은 개체의 복사본을 반환하지 않고 개체 자체를 반환한다는 것입니다. 이것은 duplicate 프로 시저가 수행해야하는 작업이 아닙니다.

내가 루비를 모르겠지만, 내가 dup 숫자에 대해 정의되지 않은 위해 생각할 수있는 가능한 이유는 같은 일을, 숫자가 기본 유형이다 따라서 : 자동

>> a = 5 
>> b = a 

을 것입니다 ba을 메모리의 동일한 값을 가리키는 것과 반대로 값 5을 변수 b에 할당하십시오.

+0

의 방법 duplicable?를 제공하는

참고. (그리고 다른 유형의 경우 원본에 대한 참조를 반환합니다) –

+0

사실이라고 가정합니다. 기능적 관점에서 볼 때 코드에 문제가없는 것 같습니다. 그러나 Ruby가 기본으로 제공하지 않는 이유는 루비의 기본 유형의 기본 제공 기능을 복제하기 때문일 가능성이 큽니다. – cmptrgeekken

관련 문제