ruby函数有多个参数

时间:2014-04-28 23:31:40

标签: ruby calculator

我正在玩创建一个函数来创建一个简单的计算器。我正在学习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。如果我在文本文件中输入数学问题,它可以完美地工作,而不是来自用户输入。

2 个答案:

答案 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
bcdenil

然后拨打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',并且方法的默认参数值将会启动。