2009-12-25 7 views
277

가능한 중복 :루비 앰퍼샌드 대장 바로 가기

some_objects.each(&:foo) 

을 그것은

some_objects.each { |obj| obj.foo } 
와 동일합니다 :

What does map(&:name) mean in Ruby?

루비에서

, 나는 내가 할 경우 알고 인

, &:foo{ |obj| obj.foo } 블록을 생성하는 PROC로 변, 각각에 전달한다. 왜이게 효과가 있니? 그냥 루비의 특별한 경우인가요? 아니면 이것이 왜 작동하는지 이유가 있습니까?

+0

이것도 같이 프레첼] 칭한다 (http://blog.honeybadger.io/how-ruby-ampersand-colon-works/) 대장 (http://technology.customink.com/blog/ 2015/06/08/ruby-pretzels /) 구문을 사용합니다. – anothermh

답변

430

여기에서 일어나고있는 것은 "는 앰퍼샌드와 객체"의 "앰퍼샌드 대장"아니다. 이 경우 콜론은 기호를 나타냅니다. 따라서 &이 있고 :foo이 있습니다.

오브젝트에

& 통화 to_proc, 및 상기 방법으로 블록으로 전달한다.

something {|i| i.foo } 
something(&:foo) 

또한, Symbolto_proc 루비 1.8.7 및 1.9에 구현되어, 그래서 사실에 "루비 것"입니다 :이 두 호출이 동일하도록 레일에서 to_procSymbol에 구현된다.

그래서 정리해 : & 개체에 to_proc를 호출 방법에 대한 블록으로 전달하고 루비 Symbolto_proc을 구현한다.

+71

좀더 정확하게 말하면 : 앰퍼샌드는'Proc' 객체를 언팩 (unpack)하여 리터럴 블록처럼 전달되도록합니다. 객체가 이미'Proc' 객체가 아닌 경우에만'to_proc'을 호출합니다. –

+0

Symbol # to_proc은 Ruby에서만 기본입니다. 1.9 –

+6

@Steve : 아니요, 1.8.7에 있습니다. p RUBY_VERSION # => "1.8.7" p [ "a", "b", "c"]지도 (& : upcase) # => [ "A", "B", "C "] –

69

앰퍼샌드와 기호의 조합에 특별한 것은 없습니다. 다음은 (ab) 정규 표현식을 사용하는 예입니다.

class Regexp 
    def to_proc 
    ->(str) { self =~ str ; $1 } 
    end 
end 
%w(station nation information).map &/(.*)ion/ 

=> ["stat", "nat", "informat"] 

또는 정수입니다.

class Integer 
    def to_proc 
    ->(arr) { arr[self] } 
    end 
end 

arr = [[*3..7],[*14..27],[*?a..?z]] 
arr.map &4 
=> [7, 18, "e"] 

당신이 arr.map &4이있을 때 누가 arr.map(&:fifth) 필요가 있겠습니까?

+3

이 예가 올바른 답변보다 좋음 – Donato