ruby приведение целого числа и строки - PullRequest
1 голос
/ 13 июля 2020

Ruby newb ie здесь.

Я пытаюсь написать очень простой калькулятор, в котором я храню числа в переменных и проверяю, включен ли ввод пользователя для оператора в массив возможные операторы, если это так, то он должен выполнить вычисление с использованием этих переменных

Есть ли способ получить результат, комбинируя эти 3 переменных? Прямо сейчас выдает мне ошибку «Строка не может быть преобразована в целое число»

puts "enter a number!"
num1 = gets.chomp().to_i
puts "enter an operator!"
op = gets.chomp()
puts "enter another number"
num2 = gets.chomp().to_i
operators = ["+", "*", "-", "/"]
result = nil

if operators.include?(op)
  result =  num1 + "#{op}" + num2
else
  puts "enter a valid operator"
end

puts result

Ответы [ 3 ]

2 голосов
/ 14 июля 2020

Давайте разберем ваш пример на что-то более простое:

num1 = 1
num2 = 2
op = '+'
result = num1 + op + num2

Когда вы пытаетесь назначить result, на самом деле происходит следующее:

result = 1 + '+' + 2

Ruby сообщает String can't be coerced into Integer, потому что он пытается добавить строку + к целому числу 1, а Ruby не может добавить строку к целому числу. Вы можете узнать больше об этом в String не может быть преобразован в Fixnum (TypeError) .

Вы можете воспроизвести это с еще более простым примером:

1 + '+'
TypeError: String can't be coerced into Integer

В вашем вопросе вы говорите , он должен выполнить расчет с использованием этих переменных , поэтому я предполагаю, что вы ожидаете, что result будет равно 3. (потому что он должен вычислять 1 + 2 из трех переменных) Это не то, что происходит в вашей строке result = ... по причинам, описанным выше.

Правильный способ сделать это - использовать public_send, как описано в эти другие вопросы и ответы здесь, в Stack Overflow:

Таким образом, ответ:

num1.public_send(op, num2)
=> 3

И интегрировано в ваш пример:

if operators.include?(op)
  result = num1.public_send(op, num2)
else
  puts "enter a valid operator"
end
1 голос
/ 14 июля 2020

Вы можете использовать public_send

num1.public_send(op, num2)

https://apidock.com/ruby/Object/public_send

Но более четким подходом было бы просто использовать операторы if / else.

if op == "+"
  num1 + num2
elsif op == "-"
  num1 - num2
elsif op == "*"
  num1 * num2
elsif op == "/"
  num1 / num2
end
0 голосов
/ 14 июля 2020

Используйте метод отправки Object #

Ваш текущий код не работает, потому что вы пытаетесь добавить op , которое в настоящее время является строкой, к целому числу. На самом деле вы хотите вызвать метод, отправив соответствующее сообщение первому целому числу, а второе число будет передано в качестве аргумента методу. Вы можете сделать это с помощью Object # send следующим образом:

print "Enter a number: "
num1 = Integer gets

loop do
  print "Enter an operator: "
  op = gets.strip
  break if %w[+ - / *].include? op
end

print "Enter another number: "
num2 = Integer gets

p num1.send(op, num2)

Помимо других модификаций и рефакторинга, использование #send позволяет этому подходу работать. Конечно, есть много других способов представить то, что вы пытаетесь сделать, но этот, безусловно, работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...