2012-04-03 3 views
4

내가 사용하고자하는 문제의 방법은 gem이며 여기에 소스 (라인 17-42)는 : 당신이 볼 수 있듯이 https://github.com/rails/rails/blob/master/railties/lib/rails/generators/actions.rb메서드가 메서드의 인수를 변경하지 못하게하려면 어떻게해야합니까?

, name은 라인 (19)의 첫 번째 인수에 할당 한 다음 messagename에 할당 라인 23에서 message<<으로 라인 26에서 돌연변이가 발생합니다. 이 불행히도 첫 번째 인수로 전달하는 문자열을 메서드 외부에서 변경된 의미합니다. 내가 막을 수있는 방법

groups => { foo: ["foo (42)", "bar (42)"], bar: ["foobar (42)"] } 

:

groups = { foo: %w(foo, bar), bar: %w(foobar) } 

groups.each do |group, gems| 
    gems.each do |name| 
    gem(name, "42") 
    end 
end 

이후 내 해시 gem의 내부의 돌연변이로 인해 다음과 같습니다 : 다음과 같이

나는 배열의 해시를하고 반복하고 이 문자열 (및 해시 및 해당 배열)은 변형되었지만 메서드가 손상되지 않았습니까?

+0

문자열을 고정하면 돌연변이가 중지되지만 예외가 발생하기 때문에! –

답변

1

당신은 name.dup로 호출 할 수 있습니다 :

gem(name.dup, "42") 

배경 : gem(name) 사용하면 통과 할 수있는 일

은과 같이, 당신의 문자열의 복제와 메소드를 호출입니다 매개 변수를 메서드에 추가합니다. 호출 된 메소드 내부의 수정은 원래 변수도 변경합니다.

name.dup을 사용하면 개체 복사본을 만들 수 있습니다. 이 복사본은 호출 된 메서드 내에서 수정되지만 원래 값은 변경되지 않습니다.


경고 : dup이 항상 작동하지 않습니다는 데이터에 따라된다. dup딥 복사본을 만들지 않습니다. 이 예를 참조하십시오

arr = ['a', 'b'] 
arr.dup.map{|x| x << '1'} 
p arr #["a1", "b1"] 

설명 : arr가 복사 배열,하지만 배열 안에있는 내용을. map 안에 복사 된 배열의 데이터를 수정합니다. 그러나 원본과 복사 된 배열의 요소는 동일합니다. 따라서 원본 배열의 내용도 변경합니다.

+0

-1. Ruby에는 참조로 인한 호출이 없습니다. 루비는 * 항상 * 가치에 의한 호출입니다. 아니야. 아뇨. 예외 없음. 예를 들면 :'def foo (bar) bar = 'reference'end; baz = '값'; foo (baz); "Ruby는 # {baz}"에 의한 호출입니다. –

+0

@ JörgWMittag'def foo (bar) bar << ',하지만 그 값은 일반적으로'end '입니다. baz = '값'; foo (baz); "루비는 # {baz}"에 의한 호출입니다. – dbenhur

+0

@ JörgWMittag 루비가 항상 가치에 의한 호출이라면, 왜 인수를 돌연변이합니까? –

5

메소드가 인수를 변형시키지 못하게 할 수 없습니다 (버그 신고를 제출하는 것 외에는하지 말아야 할 일이기 때문에).

gem(name.dup, "42") 
+1

감사! 내가 만난 바로 그 문제 때문에 논쟁을 돌이키는 것은 일반적으로 나쁜 형태로 간주됩니까? –

+4

예 - 해당 동작이 예상되고 문서화되지 않는 한 인수가 메서드에서 변경되면 안됩니다. –

관련 문제