Question:
Does Ruby safe navigation operator (&.
) evaluate its parameters when its receiver is nil
?
For example:
logger&.log("Something important happened...")
- Is the
"Something important happened..."
string evaluated here? - Could you provide an authoritative source, which proves or denies this fact?
- Or suggest a way how to check it?
Thanks in advance.
Why I am looking for an answer to this question?
I have the code like the following throughout my codebase:
logger.log("Something important happened. (#{Time.current})") if verbose
My main goal is to remove the repetition of the if verbose
check whenever I call the log
method since it is easy to forget about it and you will be not notified at all about the misusage.
Inspired by the Tell, don't ask principle,
I have moved if verbose
check inside log
method implementation.
class Logger
# ...
def log(message)
return unless verbose
# ...
end
end
def logger
@logger ||= Logger.new
end
logger.log("Something important happened. (#{Time.current})")
This approach simplified my code since I have solved my main problem - I don't need to remember to place if verbose
whenever I call the log
method,
but I have received another issue.
"Something important..."
string is always evaluated, no matter whether verbose
is true
or false
.
Therefore, I have completely changed the solution:
logger
returnsnil
whenverbose
isfalse
.- Ruby safe navigation operator should be used in front of
log
calls.
def logger
@logger ||= Logger.new if verbose
end
logger&.log("Something important happened. (#{Time.current})")
As a result, I have replaced the initial problem of remembering if verbose
checks to remembering of &.
calls.
But, anyway, I consider this as an improvement, since forgetting to utilize the safe navigation operator raises the NoMethodError
, in other words, notifies about the log
method misusage.
So now, in order to be sure that the 'safe navigation operator approach' is actually a 'better' option for my problem,
I need to know exactly whether the safe navigation operator in Ruby evaluates its parameters when its receiver is nil
.