Подтвердить что ты не робот

Почему значения параметров по умолчанию для Ruby не назначаются нильским аргументам?

Я новичок в Ruby и наткнулся на то, что меня немного смутило.

Я установил значение параметра по умолчанию в сигнатуре метода.

При вызове метода я передал аргумент nil этому параметру.

Но значение по умолчанию не было назначено; он остался nil.

# method with a default value of 1000 for parameter 'b'
def format_args(a, b=1000)
  "\t #{a.ljust(30,'.')} #{b}"
end

# test hash
dudes = {};
dudes["larry"] = 60
dudes["moe"] = nil

# expecting default parameter value
puts "Without nil check:"
dudes.each do |k,v|    
  puts format_args(k,v)
end

# forcing default parameter value
puts "With nil check:"
dudes.each do |k,v|    
  if v 
    puts format_args(k,v)
  else 
    puts format_args(k)
  end
end

Вывод:

Without nil check:
     larry......................... 60
     moe........................... 
With nil check:
     larry......................... 60
     moe........................... 1000

Является ли это ожидаемым поведением?

Какое рубиновое foo мне не хватает?

Кажется, что nil - это не то же самое "нет значения", которое я привык думать о null на других языках.

4b9b3361

Ответ 1

Параметр по умолчанию используется, когда параметр не указан.

Если вы укажете его как nil, то это будет nil. Итак, это ожидаемое поведение.

Ответ 2

Если вы хотите установить значение по умолчанию, даже если nil передано и все же разрешить вызов метода без аргумента, вам нужно установить значение по умолчанию на nil и использовать оператор "или равно":

def foo(bar=nil)
  bar ||= "default value"
  puts bar
end

Ответ 3

В Ruby методы всегда возвращают что-то. Иногда нет ничего, чтобы вернуться (запрос в базе данных становится пустым или что-то в этом роде). nil - для этих случаев; Это означает что-то вроде "ничего здесь", но это ссылка на объект. Чтобы получить нужное поведение, просто не передавайте параметр.

def talk(msg="Hello")
  puts msg
end

talk #=> "Hello"

Ответ 4

Попробуйте... v.is_nil? в инструкции if.

Ответ 5

Вы также можете использовать оператор Ruby splat (*) при вызове этого метода:

dudes.each do |k,v|    
  puts format_args(k,*v)
end

Выход:

     larry......................... 60
     moe........................... 1000