2012-10-02 4 views
0

이 질문의 제목을 지정하는 방법을 모르 셨습니다. Ruby에서 해시를 인쇄 할 때 앰퍼샌드를 사용할 수 있습니까?

은 (ENV 편리) 임의의 해시를 고려 이렇게 줄임 :

ENV.each { |key, val| puts key + ': ' + val } 
LC_MESSAGES: en_US.utf-8 
LC_COLLATE: en_US.utf-8 
PWD: /Users/baller/ive_fallen_and_i_cant_get_up 
LC_MONETARY: en_US.utf-8 

는 &를 사용할 수 있습니까?

foo.each(&:bar) 

답변

1

당신 두 개의 블록 변수를 사용하여이를 없애고 대신 하나를 가질 수 있습니다 :

each{|kv| puts kv.join(": ")} 
1

기본적으로 아니오입니다. 당신이 무엇을 기대 할 것와

class Array 
    def bar 
    puts "#{self[0]}: #{self[1]}" 
    end 
end 

, ENV.each(&:bar) :

당신은 당신이 원하는 방식으로 출력합니다 Array 클래스, 같은 뭔가 방법을 추가해야합니다, 당신이 원하는 일을합니다.

그렇긴하지만 나는 이것을 추천하지 않는다. 기본 클래스에 추가하는 것은 유틸리티가 미래의 충돌 가능성을 훨씬 능가하는 경우에만 수행해야하는 작업이며,이 메서드는 적어도 두 개 이상의 요소가있는 배열에 매우 특수화되어 있다는 사실입니다.

관련이 없지만 +을 통한 연결 문자열은 보간법을 사용할 때보 다 느립니다. 그것은 불필요하게 여분의 객체를 생성합니다.

1

예를 들어, 블록 대신에 &:bar을 사용하면 주어진 개체 (이 경우, :bar)에 대해 #to_proc이 호출됩니다. Ruby에서 Symbol을 구현 한 #to_proc은 기본적으로 foo.each(&:bar)foo.each { |i| i.bar }으로 확장합니다. 해시로부터 나온 두 개의 인수가 있으므로,이 예에서 i은 키 값 args의 배열입니다. 따라서 Array (@ x1a4에 설명 된대로)을 확장하여 해시가 & : 바를 예상대로 처리해야하는 이유입니다. 대안으로

, 당신은 #to_proc에 응답 자신의 클래스를 만들 수 있습니다 또는 단순히 PROC 같은 블록 구현 :

class Bar 
    def to_proc 
    Proc.new { |key, val| puts key + ': ' + val } 
    end 
end 

bar = Bar.new 

# or 

bar = Proc.new { |key, val| puts key + ': ' + val } 

막대에 핸들을, 당신은 블록 대신에 & 줄을 전달할 수 있습니다 ENV와 같은 해시로.

foo.each(&bar) 

이 주제에 대한 자세한 읽기 좋은 게시물 : : 컬렉션의 요소가 그 메소드에 응답하는 경우 일반적으로 http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html

1

, 이것은 가능하다 그래서 해시, foo는 주어진. 예를 들면 :

class Foo 
    attr_reader :bar 

    def initialize(bar) 
    @bar = bar 
    end 
end 

foos = [Foo.new("one"), Foo.new("two"), Foo.new("three")] 

p foos.map(&:bar) #=> ["one", "two", "three"] 

&symbol 차례로은 인수로받는 객체에 해당 메시지를 전송 블록을 반환하는 몇 가지 마술을 작동 symbol.to_proc에 대한 문법 설탕이 있기 때문에이 작동합니다.

(ENV의 개체가 :bar에 응답하지 않기 때문에)이 당신의 예를 들어 작동하지 않습니다 동안, 당신은 &를 사용하여 변수에 저장되어있어 블록을 전달할 수 있습니다

block = lambda { |key, value| puts "#{key}: #{value}" } 
ENV.each(&block) 
관련 문제