众所周知,Rubyist &
会调用to_proc
一个符号,所以
[:a, :b, :c].map(&:to_s)
相当于
[:a, :b, :c].map { |e| e.to_s } # => ["a", "b", "c"]
假设我想立即调用另一个方法to_s
,这两个实现将起作用:
[:a, :b, :c].map { |e| e.to_s.upcase } [:a, :b, :c].map(&:to_s).map(&:upcase)
我的问题是,有没有办法&
Symbol#to_proc
在一个参数中链接调用?就像是:
[:a, :b, :c].map(&:to_s:upcase)
谢谢!
如果您只是在做:
%i[a b c].map { |e| e.to_s.upcase }
然后只使用块并继续处理更重要的事情。如果您确实在进行一连串的Enumerable调用,并且发现这些块在视觉上太吵了:
%i[a b c].map { |e| e.to_s.upcase }.some_chain_of_enumerable_calls...
那么您可以将逻辑转换为lambda来帮助清理外观:
to_s_upcase = lambda { |e| e.to_s.upcase } %i[a b c].map(&to_s_upcase).some_chain_of_enumerable_calls...
或将其放入方法中并说:
%i[a b c].map(&method(:to_s_upcase)).some_chain_of_enumerable_calls...
无论哪种方式,您都在给逻辑一点点名称(这几乎&:symbol
就是您的全部工作),以使代码更易读和更易理解。在的特定情况下to_s.upcase
,这一点都没有意义,但是当块变大时,这些方法非常有用。
您需要提前定义一些方法,但这将具有普遍性.你可以这样做:
class Symbol def * other ->x{x.send(self).send(other)} end end [:a, :b, :c].map(&:to_s * :upcase) [:a, :b, :c].map(&:to_s * :capitalize) ...
我选择了*
作为功能组合的方法.
如果您认为可以使用第三个符号,则可以定义如下:
class Proc def * other ->x{call(x).send(other)} end end