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

后端 未结 16 2506
时光取名叫无心
时光取名叫无心 2020-11-21 05:34

I found this code in a RailsCast:

def tag_names
  @tag_names || tags.map(&:name).join(\' \')
end

What does the (&:name)

16条回答
  •  执笔经年
    2020-11-21 05:51

    Josh Lee's answer is almost correct except that the equivalent Ruby code should have been as follows.

    class Symbol
      def to_proc
        Proc.new do |receiver|
          receiver.send self
        end
      end
    end
    

    not

    class Symbol
      def to_proc
        Proc.new do |obj, *args|
          obj.send self, *args
        end
      end
    end
    

    With this code, when print [[1,'a'],[2,'b'],[3,'c']].map(&:first) is executed, Ruby splits the first input [1,'a'] into 1 and 'a' to give obj 1 and args* 'a' to cause an error as Fixnum object 1 does not have the method self (which is :first).


    When [[1,'a'],[2,'b'],[3,'c']].map(&:first) is executed;

    1. :first is a Symbol object, so when &:first is given to a map method as a parameter, Symbol#to_proc is invoked.

    2. map sends call message to :first.to_proc with parameter [1,'a'], e.g., :first.to_proc.call([1,'a']) is executed.

    3. to_proc procedure in Symbol class sends a send message to an array object ([1,'a']) with parameter (:first), e.g., [1,'a'].send(:first) is executed.

    4. iterates over the rest of the elements in [[1,'a'],[2,'b'],[3,'c']] object.

    This is the same as executing [[1,'a'],[2,'b'],[3,'c']].map(|e| e.first) expression.

提交回复
热议问题