What does to_proc method mean?

后端 未结 4 562
孤独总比滥情好
孤独总比滥情好 2020-11-28 23:31

I am learning rails and following this thread. I am stuck with the to_proc method. I consider symbols only as alternatives to strings (they are like strings but

相关标签:
4条回答
  • 2020-11-28 23:42

    For me the clearest explanation is seeing a simple implementation of it. Here's what it might look like if I were reimplementing Symbol#to_proc:

    class Symbol  # reopen Symbol class to reimplement to_proc method
      def to_proc
        ->(object) { object.send(self) }
      end
    end
    
    my_lambda = :to_s.to_proc
    
    puts my_lambda.(1)  # prints '1'; .() does the same thing as .call()
    puts my_lambda.(1).class  # prints 'String'
    
    puts [4,5,6].map(&:to_s)  # prints "4\n5\n6\n"
    puts [4,5,6].map(&:to_s).first.class  # prints 'String'
    
    0 讨论(0)
  • 2020-11-28 23:46

    For anybody still a bit stumped, running the following code might make things a little clearer:

    class Symbol
      def to_proc
        proc do |obj|
          puts "Symbol proc: #{obj}.send(:#{self})"
          obj.send(self)
        end
      end
    end
    
    class Array
      def map(&block)
        copy = self.class.new
        self.each do |index|
          puts "Array.map:   copy << block.call(#{index})"
          copy << block.call(index)
        end
        copy
      end
    end
    
    remapped_array = [0, 1, 2].map &:to_s
    puts "remapped array: #{remapped_array.inspect}"
    

    These are not the actual implementations of Symbol.to_proc or Array.map, they are just simplified versions which I'm using to demonstrate how map &:to_s and similar calls work.

    0 讨论(0)
  • 2020-11-28 23:58

    The easiest way to explain this is with some examples.

    (1..3).collect(&:to_s)  #=> ["1", "2", "3"]
    

    Is the same as:

    (1..3).collect {|num| num.to_s}  #=> ["1", "2", "3"]
    

    and

    [1,2,3].collect(&:succ)  #=> [2, 3, 4]
    

    Is the same as:

    [1,2,3].collect {|num| num.succ}  #=> [2, 3, 4]
    

    to_proc returns a Proc object which responds to the given method by symbol. So in the third case, the array [1,2,3] calls its collect method and. succ is method defined by class Array. So this parameter is a short hand way of saying collect each element in the array and return its successor and from that create a new array which results in [2,3,4]. The symbol :succ is being converted to a Proc object so it call the Array's succ method.

    0 讨论(0)
  • 2020-11-29 00:04

    Some methods take a block, and this pattern frequently appears for a block:

    {|x| x.foo}
    

    and people would like to write that in a more concise way. In order to do that, a symbol, the method Symbol#to_proc, implicit class casting, and & operator are used in combination. If you put & in front of a Proc instance in the argument position, that will be interpreted as a block. If you combine something other than a Proc instance with &, then implicit class casting will try to convert that to a Proc instance using to_proc method defined on that object if there is any. In case of a Symbol instance, to_proc works in this way:

    :foo.to_proc # => ->x{x.foo}
    

    For example, suppose you write like this:

    bar(&:foo)
    

    The & operator is combined with :foo, which is not a Proc instance, so implicit class cast applies Symbol#to_proc to it, which gives ->x{x.foo}. The & now applies to this and is interpreted as a block, which gives:

    bar{|x| x.foo}
    
    0 讨论(0)
提交回复
热议问题