Ruby 2.3引入了安全导航操作符,但我发现它的语法过于离散,在短暂扫描代码时很容易错过。相反,我更喜欢try
的语法,因为它看起来更加明显和有意。
所以我的问题是在Ruby 2.3+中,有没有办法将安全导航操作符&.
的方法别名或猴子修补为自定义方法名称,即。 s.fast_try(:upcase!).fast_try(:downcase)
而不是撰写s&.upcase!&.downcase
主要思想是尝试提高性能,而不是try
方法等其他实现。不,我不关心尝试和安全导航操作员之间的微小行为差异。此外,如果无法避免,我不介意一些模糊的论证限制,只需指出它们。
答案 0 :(得分:8)
我猜你可以选择像
这样简单的东西class Object
def fast_try(meth,*args,&block)
self&.public_send(meth,*args,&block)
end
end
例如:
["string","STRING","pOw"].map do |s|
s.fast_try(:upcase!)
.fast_try(:chars)
.fast_try(:find, ->{"No S"}) { |a| a == "S" }
.fast_try(:prepend, "!")
end
#=> ["!S",nil,"!No S"]
虽然您的问题表明,“不,我不关心尝试和安全导航操作员之间的轻微行为差异。”,鉴于您已经编写了一个宝石,并注意到以下内容
FastTry和ActiveSupport之间的差异#Try
我们的目标不是与try方法的ActiveSupport版本保持任何一致性。但是,我想保留一份简单的差异列表。如果您发现应在此处记录的差异,请创建PR或问题。
还没有报道
我觉得谨慎地提到,2之间存在明显的,可能是尖锐的差异,这里有Repl Spec来显示差异并且为了这个答案以及链接可能会死亡的事实该规范的输出如下:
ActiveSupport#try vs. Safe Navigation (&.)
#try
handles would be NoMethodError with nil (using #respond_to?)
does not work on a BasicObject
behaves like a method call
with no method name given
when block_given?
yields self to a block with arity > 0
evaluates block with arity == 0 in the context of self
when no block_given?
raises an ArgumentError
with a method_name given
a non nil object
uses public_send for message transmission
nil
calls NilClass#try and returns nil
#try!
does not handle NoMethodError
does not work on a BasicObject
behaves like a method call
with no method name given
when block_given?
yields self to a block with arity > 0
evaluates block with arity == 0 in the context of self
when no block_given?
raises an ArgumentError
with a method_name given
a non nil object
uses public_send for message transmission
nil
calls NilClass#try and returns nil
&. (safe navigation)
does not handle NoMethodError
raises a SyntaxError with no method name given when block_given?
raises a SyntaxError with no method name given when no block_given?
works on a BasicObject
does not act like a method call
with a method_name given
a non nil object
&. is not called
nil
returns nil without a method call
答案 1 :(得分:0)
我已根据此StackOverflow答案中的信息创建了一个gem来解决此问题。
fast_try是安全导航操作符的简单方法包装器。
功能/目标:
在初始化程序中:
FastTry.method_names = [:try, :custom_try, :try!]
require 'fast_try/apply'
用法:
str.try(:upcase).try(:downcase)
# the above statement is now equivalent to using the safe navigation operator Ex.
str&.upcase&.downcase