2015-01-18 6 views
5

I이 방법은 다음과 같이 정의 :마지막에 ** {}없이이 Ruby 메서드 호출을 만들 수 있습니까?

def woot(a = nil, b: nil) 
    ... 
end 

b가 생략되는 경우에 aHash 인스턴스를 전달하기 위해 적어도 추한 방법은 무엇인가?

나는

woot(x: 1) 
woot({x: 1}) 
h = {x: 1} 
woot(h) 

을 시도했지만 그들은 모두

ArgumentError: unknown keyword: x 

내가 더 좋은 방법이 있나요

woot({x: 1}, **{}) 

입니다 알아 낸 것을 전화를 걸 수있는 유일한 방법 인상?

+1

http://tackoverflow.com/questions/27821422/how-can-i-collapse-double-splat-arguments-into-nothing :: ** TLDNR; ** 현재 루비 임프의 버그 일 가능성이 높습니다. – mudasobwa

답변

1

첫 번째 인수는 선택 사항이므로 Ruby는 전달할 해시가 명명 된 인수 (*)를 사용한다고 가정합니다.

나는이 조금 짧은 (그러나 반드시 청소기) 비록 더 나은 해결 방법이 있다고 생각하지 않습니다 내가 당신이라면

woot({x: 1}, {}) 

내가 모호성을 해결하는 방법 서명을 변경합니다.


(*) : 음, 항상하지 : woot({1=>3}) 행복하게 최초의 선택적 인수에 해시를 전달합니다.

woot({1=> 5, :b => 4})의 경우에도 Ruby는 사전을 분할하고 {1=>5}을 첫 번째 선택적 매개 변수로 전달합니다.

은 명명 된 매개 변수를 먼저 시도하고 (기존 이름이 없다는 것에 불만을 토로 함) 다음 나머지를 선택적 매개 변수로 전달합니다.

하지만 일부 언어 변호사의 설명을보고 싶어요 ...

+0

와우, 네 말이 맞아. 그것은 더 이상합니다. 인자의 타입이 파싱되는 방식을 바꿀뿐만 아니라 인자에 포함 된 키의 타입을 바꿉니다. 최소한의 놀라움의 원칙에 너무나 많은 것. – jedediah

+0

놀랍게도 ... :) 불행히도 루비는 MRI가하는 일에 의해 대부분 "정의"되어 있기 때문에 단락을 인용하기가 어렵습니다. MRI 소스를 찾고 싶을 수도 있습니다 ... –

0

당신이 b의 기본 값을 변경하는 기대하지 않는 경우, , 방법을 명시 적으로 전달하는 방법에 대한? 물론

woot({x: 1}, b: nil) 

, b의 기본 값 변화를 하루 않는 경우, 당신은 여전히 ​​따라서 새로운 기본 값보다 뭔가 다른 그 호출에 대한 b 값을 오버라이드 (override), nil 전달 될 것입니다.