Model.all.map(&:title) 에서 &:title이 무슨 뜻인가요?

조회수 1403회

Rails에서 Model이 있고, Model.all.map(&:title)하면 무슨뜻인가요?

Ruby array에서 map을 [1, 2, 3].map { |n| n * n } #=> [1, 4, 9]이렇게 써 본 적은 있는데요.

2 답변

  • 좋아요

    9

    싫어요
    채택 취소하기

    Model.all.map(&:title)Model.all.map{ |o| o.title }과 동일하게 동작합니다.

    ruby에서 파라미터에 &가 있으면 객체가 Proc이기를 기대하는데 만약 객체가 Proc이 아니면 객체의 to_proc메소드를 호출하여 Proc으로 변환합니다. 여기서는 :title이 Symbol 객체이므로 :title.to_proc을 호출하여 Proc으로 변환되는데 Symbol#to_proc은 Symbol명에 해당하는 메소드를 호출하게 해줍니다. 그래서 Model.all.map{ |o| o.title }와 동일한 동작을 하는 것이구요.

    참고로 Symbol#to_proc은 Ruby On Rails의 ActiveSupport에 처음 등장했는데 Ruby 1.8.7에 정식으로 포함되었습니다. 내부 구현은 아래와 같습니다.

    class Symbol
      # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
      #
      #   # The same as people.collect { |p| p.name }
      #   people.collect(&:name)
      #
      #   # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
      #   people.select(&:manager?).collect(&:salary)
      def to_proc
        Proc.new { |obj, *args| obj.send(self, *args) }
      end
    end
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 자주 쓰면서도 이렇게 자세하게는 몰랐는데, 참 좋습니다. `Model.all.map(&:title.to_proc)` 과 같은 형태로도 동작을 하네요. 알 수 없는 사용자 2016.3.25 17:41
  • 찾아보니, 다음 표현은

    Model.all.map(&:title)
    

    다음의 약식(줄임) 표현이라고 합니다.

    Model.all.map { |m| m.title }
    

    결과적으로 title이라는 속성만 모아서 배열로 만들어질것 같네요.

    간단한 테스트 예제

    class TEST
      attr_reader :title
      attr_reader :number
      def initialize(title,number)
        @title = title
        @number = number
      end
    end
    m1 = TEST.new("A",1)
    m2 = TEST.new("B",2)
    m3 = TEST.new("C",3)
    
    model = [m1,m2,m3]
    
    print model.map(&:title)  #=> ["A","B","C"]
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)