Is it possible to implement the ?? operator in Ruby?
a = nil
b = 1
x = a ?? b # x should == 1
x = b ?? 2 # x should == 1
You're looking for conditional assignment:
a ||= b # Assign if a isn't already set
and the || operator
a = b || 2 # Assign if b is assigned, or assign 2
In Ruby, the short-circuiting Boolean operators (||, &&, and and or) do not return true or false, but rather the first operand that determines the outcome of the entire expression. This works, because Ruby has a rather simple idea of truth. Or rather, it has a rather simple idea of falsehood: nil is false, and obviously false is false. Everything else is true.
So, since || is true when at least one of its operands is true, and operands are evaluated from left to right, this means that a || b returns a, when a is true. But when a is false, then the outcome of the expression is solely dependent on b, and thus b is returned.
That means that, because nil is false, you can just use || instead of ?? for the examples that you gave. (There is also the nifty a ||= b operator, which kind of works like a || a = b, but not quite.)
However, that only works, because you don't use Booleans in your examples. If you expect to deal with Boolean values, that won't work:
b = false
x = b || 2 # x should be == false, but will be 2
In that case, you will have to use #nil?, and a conditional expression:
b = false
x = unless b.nil? then b else 2 end # x should be == 2
or using the ternary conditional operator:
b = false
x = b.nil? ? 2 : b # x should be == false
If you want to, you can wrap that up in a nice method:
class Object
def _? b = nil
return self
end
end
class NilClass
def _? b = nil
return yield if block_given?
return b
end
end
b = false
x = b._? { 2 } # x should be == false
x = b._? 2 # x should be == false
This cute snippet brought to you by polymorphism, open classes and the fact that nil is actually an object representing nothingness (unlike, say, Java, where null is actually nothing).
x = b || 2
It (?? in C#) is called the coalesce operator.
There is the coalesce gem, which is as close as you'll get.
nil || 5 # => 5
false || 5 # => 5 :(
false._? 5 # => false :)
来源:https://stackoverflow.com/questions/953216/c-sharp-operator-in-ruby