DRY up Ruby ternary
I often have a situation where I want to do some conditional logic and then return a part of the condition. How can I do this without repeating the part of the condition in the true or false expression?
For example:
ClassName.method.blank? ? false : ClassName.method
Is there any way to avoid repeating ClassName.method
?
Here is a real-world example:
PROFESSIONAL_ROLES.key(self.profes开发者_运维知识库sional_role).nil? ?
948460516 : PROFESSIONAL_ROLES.key(self.professional_role)
Assuming you're okay with false
being treated the same way as nil
, you use ||
:
PROFESSIONAL_ROLES.key(self.professional_role) || 948460516
This will return 948460516
if key
returns nil
or false
and the return value of the call to key
otherwise.
Note that this will only return 948460516 if key
returns nil
or false
, not if it returns an empty array or string. Since you used nil?
in your second example, I assume that's okay. However you used blank?
in the first example (and blank?
returns true
for empty arrays and strings), so I'm not sure.
If you just want to DRY, then you can use a temp variable:
x = ClassName.method
x.blank? ? false : x
x = PROFESSIONAL_ROLES.key(self.professional_role)
x.nil? ? 948460516 : x
If you don't want to use a temp variable, you can use a block:
Proc.new do |x| x.blank? ? false : x end.call(ClassName.method)
Proc.new do |x| x.nil? ? 948460516 : x end.call(PROFESSIONAL_ROLES.key(self.professional_role))
For the cases you describe (where you just want to use the original value when a default-check fails), it'd be straightforward to write a helper method:
def x_or_default(x, defval, checker = :nil?)
if x.send(checker) then defval else x end
end
x_or_default(ClassName.method, false, :blank?)
x_or_default(PROFESSIONAL_ROLES.key(self.professional_role), 94840516)
which is very similar to the ||
method described, but would also work with your blank?
example.
I usually use temporary variables for this sort of thing.
I know this doesn't look too pretty, but it does make things a bit DRYer.
a = "ABC"
b = (temp = a.downcase).length < 3 ? "---" : temp
If you don't want to create temp
variable for whatever reason, you could reuse something that already exists like $_
.
精彩评论