2012-11-10 5 views
2

사용자가 단일 개체 또는 배열 중 하나가 될 수있는 메서드에 옵션을 전달할 수 있도록 허용하고 싶습니다. [이 : variable_length_opt]가 정의됩니다Ruby 스 플랫 사용시 오류가 발생하는 이유는 무엇입니까?

def initialize(opts={}) 
    @ivar = *opts[:variable_length_opt] 
end 

을 그러나 나는 또한 옵션이 설정되지 않은 경우 기본값을 설정할 수 있도록하고 싶습니다 아래의 코드는 가정 일`의 opts. 하지만이 코드는 작동하지 않습니다

def initialize(opts={}) 
    @ivar = (opts[:variable_length_opt] ? *opts[:variable_length_opt] : default_value) 
end 

는 그것은 unexpected tSTAR 오류가 발생합니다. 나는 내가 한 일을 성취하기위한 다른,보다 장황한 방법이 있다는 것을 이해하지만 다른 짧은 대안이 있는지 궁금해하고 있습니다. 또한, 스 플랫의 한계는 무엇입니까? 나는 그것이 여기 사용할 수 없어야하는 좋은 이유를 생각할 수 없다.

답변

5

스플래트는 대입 (및 간접적으로, 메서드 호출에서)에서만 사용할 수 있다고 생각합니다. 직접 하나 플랫를 호출 할 수 없습니다 : 거의 짧은

def initialize(opts={}) 
    @ivar = *(opts[:variable_length_opt] ? opts[:variable_length_opt] : [default_value]) 
end 

: 귀하의 경우

1.9.3p286 :045 > *[1,2,3,4] 
SyntaxError: (irb):45: syntax error, unexpected '\n', expecting tCOLON2 or '[' or '.' 
    from /Users/fcoury/.rvm/rubies/ruby-1.9.3-p286/bin/irb:16:in `<main>' 

, 당신이 뭔가를 할 수 있습니다.

a = [1,2,3,4] 
b, c, d, e = *a 
b #=> 1 
C#=> 2 ... 

같은

하지만 일반적으로 배열에서 여러 변수를 할당하는 플랫를 사용, 왜이 경우 플랫 필요합니까? 대신에 실제로 당신이 기본값으로 opts 해시를 초기화 할 수있는 원을 사용

+1

감사합니다. 나는 외부에 스 플랫을 두는 것을 생각하지 않았지만, 필요한 것일뿐입니다. 실제로는 default_value를 목록 괄호에 넣지 않고도 작동해야합니다. 왜 내가 splat을 필요로하는지에 대한 목적은 사용자가 배열이나 단일 객체를 옵션으로 전달할 수있게하는 것입니다. splat은 배열에 단일 객체를 래핑하고 배열은 그대로 둡니다. 이렇게하면 @ivar를 배열로 취급하는 나머지 코드를 작성할 수 있습니다. 한 가지 더 - 위의 다중 할당 예제에서 실제로는 (적어도 Ruby 1.9.3에서는) 표시가 필요하지 않습니다. 그것을 시도하고 볼! –

+0

당신은 할당에 대해 절대적으로 옳고 1.8.7에서도 작동합니다. – kolrie

0

- 무엇을 Hash.new("default_value")

class InitOptions 
    attr_reader :ivar 

    def initialize(opts=Hash.new("default_value")) 
     @ivar = *opts[:variable_length_opt] 
    end 
end 

p InitOptions.new({:variable_length_opt => [1,2,3,4]}).ivar #=> [1, 2, 3, 4] 
p InitOptions.new.ivar # => ["default_value"] 

는 대신 해시에 존재하지 않는 몇 가지 키, 그것은 어떤 값을 반환 할 때 nil를 반환 이 경우에 초기화하기 위해 전달했습니다. default_value

+0

감사합니다. Ashish. 이것은 옵션 해시에 단 하나의 항목 만있는 경우 꽤 잘 작동하지만 여러 항목 (자체 고유 한 가능성이있는 다른 기본값이 필요함)으로 확장되지 않습니다. 아니, 내 질문에 언급했다. –