我正在玩创建一个函数来创建一个简单的计算器。我正在学习Ruby / Python。到目前为止,我正在玩Ruby,看看我是否能比Python更容易掌握它。我正在阅读电子书,并了解如何在函数中使用多个参数。
#!/bin/ruby
def menu()
print <<MENU
1.Add
2.Subtract
3.Multiply
4.Divide
MENU
end
def calc(a=number, b=operator, c=number, d=operator, e=number)
puts "Answer: #{a} #{b} #{c} #{d} #{e}"
end
puts "Enter formula, seperated by comma"
a,b,c,d,e = gets()
calc(a,b,c,d,e)
是我的来源,请记住这不是一个二手程序。就像现在一样,它打印了#34;答案&#34;作为一个字符串。
因此,如果我输入1+3
,则答案为1+3
。但是,如果我使用gets().to_f
,则每次都会打印1.0
。如果我在文本文件中输入数学问题,它可以完美地工作,而不是来自用户输入。
答案 0 :(得分:1)
嗯,这里有一些事情发生。
首先,你的函数定义:
def calc(a=number, b=operator, c=number, d=operator, e=number)
这应该是def calc(a=nil, b=nil, c=nil, d=nil, e=nil)
我理解该示例告诉我,用户,a
应该是一个数字,b
应该是一个运算符等,但是当你实际定义一个函数时,你是什么的正在做的是设置参数的默认值。当您在定义中使用'number'和'operator'时,它们没有任何值,最终将nil指定为默认值。最终的结果是一样的,但是阅读代码的任何人都会感到困惑。
接下来,我了解您要对a,b,c,d,e = gets()
进行的操作
如果你只是运行
a,b,c,d,e = 1,2,3,4,5
puts a,b,c,d,e #=>
1
2
3
4
5
有道理。但是,当您运行Ruby脚本并使用gets()
时,在命令行输入的所有内容都将作为单个字符串接收。因此,执行a,b,c,d,e = gets()
时,“1 + 3”的用户输入将被视为字符串并分配给a
。
b
,c
,d
和e
为nil
然后拨打calc("1+3",nil,nil,nil,nil)
calc
然后评估它的一行方法定义,如下所示:
puts "Answer: #{"1+3"} #{nil} #{nil} #{nil} #{nil}"
这就是为什么你只看到“答案:1 + 3”作为输出。
那么,如果你硬编码a,b,c,d,e=2*7+1
,为什么会这样呢?
评估该行时,首先评估2*7+1
(15)。然后将15分配给a
,所有其他变量都是nil
,就像之前一样。然后calc
只打印出a
的值,即15。
所以....让我们看看如何让这个例子像你期望的那样工作
首先,我将忽略menu
方法,因为它实际上并未在示例中的任何位置使用过。
#!/bin/ruby
def calc(user_input)
result = eval(input_string)
puts "Answer: #{result}"
end
puts "Enter formula"
user_input = gets()
# e.g. "1+3*8"
calc(user_input)
我所做的只是eval
使用输入的字符串。 对eval
要非常小心。在这种情况下我永远不会真正使用它,因为用户可以输入任何类型的ruby脚本,你的程序就可以运行它。 Here is an SO question演示了在评估公式之前如何实施检查。
答案 1 :(得分:0)
我相信您的代码中缺少的是split
gets
答案:
#!/bin/ruby
def menu()
print <<MENU
1.Add
2.Subtract
3.Multiply
4.Divide
MENU
end
def calc(a, b, c, d, e)
puts "Answer: #{a} #{b} #{c} #{d} #{e}"
end
puts "Enter formula, seperated by comma"
a,b,c,d,e = gets.split('')
calc(a,b,c,d,e)
现在,当用户输入2*7+1
时,您将获得Answer: 2 * 7 + 1
,然后您可以开始实施您的代码:
def calc(a, b=:+, c=0, d=:+, e=0)
puts a.to_f.send(b, c.to_f).send(d, e.to_f)
end
现在您的回答是15.0
。
不要使用EVAL ,特别是当你期望结构化时 - 这是一个严重的安全漏洞!
要使代码支持少于5个元素,您需要将其更改为:
params = gets.chomp.split('')
calc(*params)
这样,缺少的元素将不会被评估为'nil',并且方法的默认参数值将会启动。