2010-02-24 5 views
3

Что здесь происходит?принуждение ноль к числу

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> 

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

ответ

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).

5

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

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

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

+0

Я лично предпочитаю 'или' над' || ', это просто проще для многих людей читать (хотя я сделал достаточно программирования, что я заканчиваю чтение' || 'как" или "anyways: P). – Amber

+0

@ Dav: как насчет синтаксиса '@foo || = ...'? Я использую его много, так почему бы не всегда использовать '||'? На самом деле я просто рационализирую: я просто предпочитаю '||' over' или' :) – giorgian

+0

'||' также имеет приоритет над 'или', поэтому они не всегда взаимозаменяемы. –

3

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

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

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

+1

<3 прямые ответы на вопросы. – nmr