我想知道为什么命名参数不能像我预期的那样工作。
def my_method(var1, var2 = 1, var3 = 10)
puts var1, var2, var3
end
my_method(999, var3 = 123)
输出
999
123
10
而不是(至少,我认为应该如此):
999
1
123
那么,我该怎么做才能使用命名参数?
P.S。当我使用哈希时,它不是我正在寻找的东西:
def my_method(var1, vars = {var2: 1, var3: 10} )
puts var1, vars[:var2], vars[:var3]
end
my_method(999, var3: 123)
999
123
my_method(999, var2: 111, var3: 123)
999
111
123
my_method(999)
999
1
10
所以我必须覆盖vars
的每个值,或者根本不覆盖它们。有没有更便捷的方式?
答案 0 :(得分:3)
在ruby my_method(999, var3 = 123)
中表示,为var3
分配值123
并将其传递给my_method
。
没有命名参数的概念,但是,您可以使用哈希作为my_method
的参数,例如:
def my_method(args = {})
p "#{args[:a]}, #{args[:b]}, #{args[:c]}"
end
然后你可以用:
来调用它my_method(b: 2, c: 3, a: 1)
将打印1, 2, 3
,因为b: 2, c: 3, a: 1
被推断为ruby的哈希值。您也可以使用以下方式显式指示哈希:
my_method({b: 2, c: 3, a: 1})
答案 1 :(得分:2)
正如所指出的,Ruby没有关键字参数(但它们是2.0版本)。为了实现您的目标,options
哈希是一种非常常见的Ruby习惯用法。
def my_method(var1, options = {})
var2 = options.fetch(:var2, 1)
var3 = options.fetch(:var3, 10)
puts var1, var2, var3
end
my_method(999)
# => 999, 1, 10
my_method(999, var3: 123)
# => 999, 1, 123
my_method(999, var2: 111)
# => 999, 111, 10
my_method(999, var2: 111, var3: 123)
# => 999, 111, 123
my_method()
# => ArgumentError: wrong number of arguments (0 for 1)
请注意,使用options.fetch(:key, default)
而不是options[:key] || default
通常更可取,因为它允许您明确指定虚假值(即false
和nil
)。
options = {x: nil, y: false}
x = options[:x] || 42 # sets x to 42
x = options.fetch(:x, 42) # sets x to nil
y = options[:y] || 43 # sets y to 43
y = options.fetch(:y, 43) # sets y to false
z = options[:z] || 44 # sets z to 44
z = options.fetch(:z, 44) # sets z to 44
你甚至可以将一个块传递给fetch
,这允许你推迟计算默认值:
options.fetch(:x) { some_expensive_calculation }
# some_expensive_calculation is only called if necessary
答案 2 :(得分:1)
您可以使用此
def my_method(options = {})
puts options[:var1] || ''
puts options[:var2] || ''
puts options[:var3] || ''
end
使用
进行通话my_method(var1:999, var3: 123)
或
my_method(var1:999)
答案 3 :(得分:1)
你也可以玩这样的东西:
def method(data)
defaults = {var2: 1, var3: 10}
(@var1, @var2, @var3) = defaults.merge(data).values_at(:var1, :var2, :var3)
p @var1, @var2, @var3
end
method(var1: 999, var3: 123)
答案 4 :(得分:1)
Ruby 2.0.0已发布,现在您可以使用命名参数。
def my_method(var1, var2: 1, var3: 10)
puts var1, var2, var3
end
my_method(999, var3: 123)
结果:
999
1
123
或另一个例子:
def foo(str: "foo", num: 100)
[str, num]
end
p foo(str: 'buz', num: 1) #=> ['buz', 1]
p foo(str: 'bar') # => ['bar', 100]
p foo(num: 2) # => ["foo", 2]
p foo # => ['foo', 100]
p foo(bar: 'buz') # => ArgumentError