принуждение нуля к числу

Что здесь происходит??

irb(main):001:0> a= nil
=> nil
irb(main):002:0> b = nil
=> nil
irb(main):003:0> a
=> nil
irb(main):004:0> a+b
NoMethodError: undefined method `+' for nil:NilClass
    from (irb):4
    from :0
irb(main):005:0> if a.nil? or b.nil?; a,b=0;end;
irb(main):006:0* c = a+b
TypeError: nil can't be coerced into Fixnum
    from (irb):6:in `+'
    from (irb):6
    from :0
irb(main):007:0>

Как можно безопасно выполнять арифметические действия, преобразовывая ноль в число?


person eastafri    schedule 24.02.2010    source источник


Ответы (3)


Почему вы хотите добавить nil? Он специально разработан для обозначения отсутствия значения (примечание: nil НЕ 0).

Если на самом деле вы хотите установить для обоих значений значение 0, если одно из них равно в настоящее время nil, то на самом деле вам нужно следующее:

if a.nil? or b.nil?; a,b=0,0; end

Вашей ошибкой в ​​приведенном выше коде была часть a,b=0, которая устанавливает только значение a в 0 - она ​​устанавливает b в nil, потому что левая часть ищет два значения, а справа предоставляется только одно (поэтому остальные предполагается nil).

person Amber    schedule 24.02.2010

В зависимости от того, почему вместо числа стоит ноль, вы можете решить, что для вас хорошо рассматривать ноль как 0; в этом случае вы можете сделать что-то вроде:

c = (a || 0) + (b || 0)

Это, конечно, имеет смысл только в том случае, если вы знаете, почему у вас ноль вместо числа...

person giorgian    schedule 24.02.2010
comment
Я лично предпочитаю or ||, просто многим людям проще читать (хотя я достаточно программировал, чтобы читать || как или в любом случае :P). - person Amber; 24.02.2010
comment
@Dav: как насчет синтаксиса @foo ||= ...? Я часто его использую, так почему бы не использовать всегда ||? На самом деле я просто рационализирую: я просто предпочитаю || or :) - person giorgian; 24.02.2010
comment
|| также имеет приоритет над or, поэтому они не всегда взаимозаменяемы. - person Jimmy; 24.02.2010
comment
На самом деле этот приоритет мне нравится, Джимми - на мой взгляд, || лучше сохранить для реальных логических операций большую часть времени; сохраняя or для фактического, иногда мне нужно фактическое второе значение. - person Amber; 24.02.2010

Ваше параллельное присвоение (a, b = 0) приводит к a=0 и b=nil, т. е. оно присваивает 0 a и nil b, потому что в правой части есть только одно значение.

Что вы хотите: если a.nil? или b.nil?; а = б = 0; конец с = а + б

Очевидно, код по-прежнему неисправен, поскольку вы перезаписываете любые ненулевые значения a и b на 0, когда a или b равны нулю.

person liwp    schedule 24.02.2010
comment
‹3 прямых ответа на вопросы. - person nmr; 13.12.2011