我正在尝试创建一个可以通过以下方式调用的方法:
instance.respond('some command', 'command arg 1', 'command arg 2', 'command arg 3')
instance.respond(true, 'some command', 'command arg 1', 'command arg 2', 'command arg 3')
instance.respond(false, 'some command', 'command arg 1', 'command arg 2', 'command arg 3')
true
/ false
值表示命令是应该立即发送还是缓冲发送。
我尝试定义方法,如下例所示:
class Foo
def bar1(arg1=true, arg2)
puts 'this works'
end
def bar2(arg1, *args)
puts 'this works as well'
end
def bar3(arg1=true, arg2, *args)
puts 'but this fails'
end
end
运行此命令会出现错误:
/opt/dl/testcase.rb:10: syntax error, unexpected *
def bar3(arg1=true, arg2, *args)
^
/opt/dl/testcase.rb:13: syntax error, unexpected keyword_end, expecting end-of-input
有没有办法解决这个问题,或解决它?
答案 0 :(得分:3)
由于您没有指定您使用的是哪个ruby版本,我将假设版本> = 2没问题。如果这个问题只是修复语法错误,那么你可以编写像
这样的东西class A
def respond(flag = true, b = '', *args)
"flag=#{flag}, b=#{b} args=#{args.join(',')}"
end
end
但是,您遇到一些问题:
A.new.respond('some command', 'command arg 1', 'command arg 2', 'command arg 3')
#=> flag=some command, b=command arg 1 args=command arg 2,command arg 3
A.new.respond(true, 'some command', 'command arg 1', 'command arg 2', 'command arg 3')
#=> flag=true, b=some command args=command arg 1,command arg 2,command arg 3
A.new.respond(false, 'some command', 'command arg 1', 'command arg 2', 'command arg 3')
#=> flag=false, b=some command args=command arg 1,command arg 2,command arg 3
使用命名参数的方法会更安全。例如,您可以执行类似
的操作class B
def respond(flag: true, b:, **args)
"flag=#{flag}, b=#{b} args=#{args.values.join(',')}"
end
end
args = {
c1: "command arg 1",
c2: "command arg 2",
c3: "command arg 3"
}
B.new.respond(b: 'some command', **args)
#=> flag=true, b=some command args=command arg 1,command arg 2,command arg 3
B.new.respond(flag: true, b: 'some command', **args)
#=> flag=true, b=some command args=command arg 1,command arg 2,command arg 3
B.new.respond(flag: false, b: 'some command', **args)
#=> flag=false, b=some command args=command arg 1,command arg 2,command arg 3
答案 1 :(得分:1)
@simplaY已经显示了如何在这里使用命名参数。如果必须支持2.0之前的Ruby版本(当命名参数首次亮相时),则有一些选项。
<强>#1 强>
def respond(*args)
flag = true # default
flag = args.shift if [true, false].include? args.first
puts "flag = #{flag}"
puts "args = #{args}"
if flag
# code
else
# code
end
end
respond "dog", "cat"
flag = true
args = ["dog", "cat"]
respond false, "dog", "cat"
flag = false
args = ["dog", "cat"]
这当然要求第一个参数的允许值为true
或false
当且仅当它是flag
的值时。
<强>#2 强>
def respond(flag=true, args)
if flag
# code
else
# code
end
end
称为
respond ["dog", "cat"]
respond true, ["dog", "cat"]
respond true, ["dog", "cat"]
每当一个方法具有可变数量的参数时,规则就是当它并且只有对你来说是明确的时候它才是明确的。
<强>#3 强>
def respond(options)
flag = options.fetch(:flag, true)
if flag
# code
else
# code
end
end
称为
respond(arg1: 'dog', arg2: 'cat')
respond(flag: false, arg1: 'dog', arg2: 'cat')
在Ruby 2.0之前广泛使用的最后一种方法已经在很大程度上被使用命名参数所取代,部分原因是命名参数显示其值被传递的键,而在最后一种方法中,只识别哈希值在方法的论点中。