Mar*_*n13 4 ruby safe-navigation-operator
Ruby 安全导航操作符 ( &.) 是否在其接收器为 时评估其参数nil?
例如:
logger&.log("Something important happened...")
Run Code Online (Sandbox Code Playgroud)
"Something important happened..."字符串是在这里求值的吗?提前致谢。
我的代码库中有如下代码:
logger&.log("Something important happened...")
Run Code Online (Sandbox Code Playgroud)
我的主要目标是if verbose在我调用该log方法时消除重复检查,因为很容易忘记它,并且您根本不会收到有关误用的通知。
我已经if verbose在log方法实现中移动了检查。
logger.log("Something important happened. (#{Time.current})") if verbose
Run Code Online (Sandbox Code Playgroud)
这种方法简化了我的代码,因为我已经解决了我的主要问题 -if verbose每次调用该log方法时我都不需要记住放置,
但我收到了另一个问题。
"Something important..."字符串总是被评估,无论verbose是true还是false。
因此,我彻底改变了解决方案:
logger返回nil时verbose是false。log调用前使用。class Logger
# ...
def log(message)
return unless verbose
# ...
end
end
def logger
@logger ||= Logger.new
end
logger.log("Something important happened. (#{Time.current})")
Run Code Online (Sandbox Code Playgroud)
结果,我已经将记住if verbose检查的最初问题替换为记住&.电话。
但是,无论如何,我认为这是一种改进,因为忘记使用安全导航操作符会引发NoMethodError,换句话说,通知log方法误用。
所以现在,为了确保“安全导航操作员方法”实际上是解决我的问题的“更好”选择,
我需要确切地知道 Ruby 中的安全导航操作符是否在其接收器为nil.
引用安全导航操作符的语法文档:
&.,称为“安全导航操作符”,允许在接收者为 时跳过方法调用nil。如果跳过调用,它会返回nil并且不评估方法的参数。
因此,您的参数log方法不被评估,如果logger是nil,当你把它作为
logger&.log("something happened at #{Time.now}")
Run Code Online (Sandbox Code Playgroud)
话虽如此,请注意 Ruby 核心记录器为您的确切问题提供了不同的解决方案,即避免在日志级别过高时评估潜在的昂贵参数。
Ruby 核心记录器实现其add方法如下(简化):
class Logger
attr_accessor :level
def initialize(level)
@level = level.to_i
end
def add(severity, message = nil)
return unless severity >= level
message ||= yield
log_device.write(message)
end
def info(message = nil, &block)
add(1, message, &block)
end
end
Run Code Online (Sandbox Code Playgroud)
然后您可以将其用作
logger = Logger.new(1)
logger.info { "something happened at #{Time.now}" }
Run Code Online (Sandbox Code Playgroud)
在这里,只有当日志级别足够高以至于实际使用消息时才会评估块。
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |