С#? оператор в Рубине?
Возможно ли реализовать его ?? оператор в Рубине?
a = nil
b = 1
x = a ?? b # x should == 1
x = b ?? 2 # x should == 1
4 ответа:
Вы ищете условное назначение:
a ||= b # Assign if a isn't already set
И оператор | |
a = b || 2 # Assign if b is assigned, or assign 2
В Ruby булевы операторы короткого замыкания (
||
,&&
,and
иor
) возвращают неtrue
илиfalse
, а первый операнд, который определяет результат всего выражения. Это работает, потому что Руби имеет довольно простое представление об истине. Или, скорее, у него есть довольно простая идея лжи:nil
ложно, и очевидно, чтоfalse
ложно. все остальное истинно.Итак, поскольку
Это означает, что, поскольку||
истинно, когдахотя бы один из его операндов истинен, и операнды вычисляются слева направо, это означает, чтоa || b
возвращаетa
, Когдаa
истинно. Но когдаa
ложно, то результат выражения зависит исключительно отb
, и таким образомb
возвращается.nil
является ложным, вы можете просто использовать||
вместо??
для приведенных вами примеров. (Есть также отличный операторa ||= b
, который работает какa || a = b
, но не совсем.)Однако, что работает только , потому что вы не используете логические значения в своих примерах. Если вы ожидаете иметь дело с логическими значениями, это не сработает:
b = false x = b || 2 # x should be == false, but will be 2
В этом случае вам придется использовать
#nil?
и условное выражение:b = false x = unless b.nil? then b else 2 end # x should be == 2
Или с помощью тернарного условного оператора:
b = false x = b.nil? ? 2 : b # x should be == false
Если вы хотите, вы можете обернуть это в хороший метод:
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
Этот милый фрагмент принес вам полиморфизм, открытые классы и тот факт, что
nil
на самом деле является объектом , представляющим небытие (В отличие, скажем, от Java, гдеnull
является фактически ничем).
Естьслияние драгоценный камень, который находится так близко, как вы можете получить.
nil || 5 # => 5 false || 5 # => 5 :( false._? 5 # => false :)