C#? оператор в Руби?

можно ли реализовать ?? оператор в Руби?

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 ложно. все остальное - это правда.

так, с || истинно at хотя бы один!--29--> его операндов истинно, и операнды оцениваются слева направо, это означает, что a || b возвращает a, когда a - это правда. Но когда!--14--> является ложным, то результат выражения зависит исключительно от b и так b возвращается.

это значит, что, потому что nil имеет значение false, вы можете просто использовать || вместо ?? для примеров, которые вы дали. (Есть также nifty 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 и на самом деле ничего).


x = b || 2

Он (?? в C#) называется оператором сливаются.


есть коалесцируют gem, который так близко, как вы получите.

nil || 5 # => 5
false || 5 # => 5 :(
false._? 5 # => false :)