2015-09-06 1 views
-1

Я пытаюсь написать программу для создания факториалов. Я сделал это:'*' не может быть принудительно введен в Fixnum (TypeError)

continue_loop=true 

def fact(n) 
    if n==0 
    1 
    else 
    n*fact(n-1) 
    end 
end 

while continue_loop 
    puts "Welcome to the factorial machine. Write a number! Write exit to exit the program" 
    user=gets.chomp 
    if user=="exit" 
    continue_loop=false 
    else puts fact(user.to_i) 
    puts "--------" 
    end 
end 

я * can't be coerced into Fixnum(TypeError) на линиях:

n*fact(n-1) 

и

else puts fact(user.to_i) 

я обнаружил, что я получаю эту ошибку, потому что правая сторона n*fact(n-1) является nil. Но тогда я не вижу, как я могу сделать рекурсию.

Это можно сделать с помощью inject, но я хотел бы научиться использовать рекурсию.

+0

Ваша программа кажется прекрасной, я просто скопировал ее, и она отлично работала. Не могли бы вы попытаться воспроизвести это в онлайн-интерпретаторе? https://repl.it/languages/ruby –

+0

Что вы хотите сказать? – sawa

+1

@sawa Спасибо за исправление и извините за свои ошибки, английский не мой родной язык, и, как вы можете видеть, я совершенно новый для программирования). Я постараюсь не делать их в будущих вопросах (а также в том числе и в актуальном вопросе). – Lenok

ответ

0

Ваша функция:

def fact(n) 
    if n==0 
     1 
    else 
     n*fact(n-1) 
    end 
end 

прекрасно. if/else возвращает значения из обоих блоков. Просто, чтобы быть уверенным, что я только что попробовал с fact(5), и он вернул 120. Если что-то не так, это не так. Конечно, ваша функция fact(-1) терпит неудачу, но это еще одна проблема.

Ваша функция не может вернуть нуль. Он либо вернет 1, либо результат умножения. Поэтому в n*fact(n-1) правая рука не может быть равна нулю. Возможно, левая рука. Узнайте, почему.

+0

Извините, но я не вижу, как левая сторона может быть «nil». – Lenok

+0

@Lenok: Честно говоря, я слепо предположил, что 'user.to_i' будет генерировать ошибочное значение, когда вводится какой-то мусор. Я не думал, что это будет «ноль». Тем не менее, я проверил ваш код, и он отлично работает даже для ввода мусора (кроме негативов, где он получает переполнение стека). Затем я вспомнил, что 'to_i' возвращает' 0', когда преобразование невозможно, поэтому, ну, здесь нет ник. Теперь, когда я перечитываю сообщение об ошибке, он утверждает, что '*' не может быть преобразован, а не 'nil'. Это может указывать на то, что 'n' может быть == до' '*" '(строка со звездочкой) или что-то похожее на уровень странности. – quetzalcoatl

+0

, но даже когда я попробовал это, 'to_i' просто вернул' 0', как и для ввода мусора. Итак, я не знаю. Так как ваша программа начала работать после перезагрузки IRB, это должно было быть случайным повреждением этой сессии (что-то вроде случайного переопределения какого-то базового метода, такого как &: * или to_s). Или, может быть, ошибка в IRB? Извините, из идей. – quetzalcoatl

Смежные вопросы