Chaining & to_proc on symbol

后端 未结 5 751
深忆病人
深忆病人 2020-12-09 22:26

It\'s well known to Rubyist & will call to_proc on a symbol, so

[:a, :b, :c].map(&:to_s)

is equivalent to

5条回答
  •  北海茫月
    2020-12-09 22:57

    So just for fun (and to prove that almost anything is possible in ruby if one puts in a bit of effort) we could define a method on Symbol (we'll call it Symbol#chain) to provide this functionality and a little more

    class Symbol
      def proc_chain(*args)
        args.inject(self.to_proc) do |memo,meth|
          meth, *passable_args = [meth].flatten
          passable_block = passable_args.pop if passable_args.last.is_a?(Proc)
          Proc.new do |obj|
            memo.call(obj).__send__(meth,*passable_args,&passable_block)
          end
        end
      end
      alias_method :chain, :proc_chain
    end
    

    This can then be called like so

    [:a, :b, :c].map(&:to_s.chain(:upcase))
    #=> ["A","B","C"]
    # Or with Arguments & blocks
    [1,2,3,4,5].map(&:itself.chain([:to_s,2],:chars,[:map,->(e){ "#{e}!!!!"}]))
    #=>  => [["1!!!!"], ["1!!!!", "0!!!!"], ["1!!!!", "1!!!!"],
    #        ["1!!!!","0!!!!", "0!!!!"], ["1!!!!", "0!!!!", "1!!!!"]]
    

    Can even be used as a standalone

    p = :to_s.chain([:split,'.'])
    p.call(123.45)
    #=> ["123","45"]
    # Or even 
    [123.45,76.75].map(&p)
    #=> => [["123", "45"], ["76", "75"]]
    

提交回复
热议问题