Débutant Ruby ici.
J'essaie d'écrire une calculatrice très simple où je stocke les nombres dans des variables et vérifie si l'entrée utilisateur pour l'opérateur est incluse dans le tableau des opérateurs possibles, si c'est alors ça devrait effectuer le calcul en utilisant ces variables
Est-il possible d'obtenir le résultat de la combinaison de ces 3 variables? En ce moment, me lance l'erreur "La chaîne ne peut pas être forcée en nombre entier"
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 Réponses :
Vous pouvez utiliser public_send
if op == "+" num1 + num2 elsif op == "-" num1 - num2 elsif op == "*" num1 * num2 elsif op == "/" num1 / num2 end
https://apidock.com/ruby/Object/public_send
Mais une approche plus claire consisterait simplement à utiliser des instructions if / else.
num1.public_send(op, num2)
Au lieu de if / elsif , vous pouvez utiliser un case expression pour éviter de répéter la comparaison.
Votre code actuel ne fonctionne pas car vous essayez d'ajouter op , qui est actuellement une chaîne, à un entier. Ce que vous voulez faire est d'appeler la méthode en envoyant le message approprié au premier entier, avec le deuxième nombre passé comme argument à la méthode. Vous pouvez le faire avec Object # send comme suit:
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)
Outre les autres modifications et refactorisations, c'est l'utilisation de #send qui permet à cette approche de fonctionner. Il existe certainement de nombreuses autres façons de représenter ce que vous essayez de faire, mais celle-ci fonctionne certainement.
Décomposons votre exemple en quelque chose d'un peu plus simple:
if operators.include?(op) result = num1.public_send(op, num2) else puts "enter a valid operator" end
Lorsque vous essayez d'attribuer un résultat , voici ce qui se passe réellement:
XXX
Rapports Ruby La chaîne ne peut pas être forcée en Integer car elle tente d'ajouter la chaîne + à l'entier 1 et Ruby ne peuvent pas ajouter de chaîne à un entier. Vous pouvez en savoir plus à ce sujet sur La chaîne ne peut pas être forcée dans Fixnum (TypeError) .
Vous pouvez le reproduire avec un exemple encore plus simple:
num1.public_send(op, num2) => 3
Dans votre question, vous dites qu'il devrait effectuer le calcul en utilisant ces variables donc je suppose que vous vous attendez à ce que le résultat soit égal à 3 . (car il devrait calculer 1 + 2 à partir des trois variables) Ce n'est pas ce qui se passe dans votre ligne result = ... pour les raisons décrites ci-dessus.
La bonne façon de faire est d'utiliser public_send comme décrit dans ces autres questions et réponses ici sur Stack Overflow:
Ainsi la réponse est:
1 + '+' TypeError: String can't be coerced into Integer
Et intégrée dans votre exemple:
result = 1 + '+' + 2
Je ne sais pas trop ce que vous entendez par «combinaison». Quel est votre résultat attendu pour
num1 = 1,op = "+"etnum2 = 2? La chaîne"1 + 2"ou l'entier3?