有没有办法让参数真正可选,所以我知道它是否是由调用者设置的?
使用nil
作为默认值的参数不起作用,因为无法知道调用者是否通过了nil
,或者它是参数的默认值。
在命名参数之前,在Ruby 1.9中,使用选项哈希:
def foo(options = {})
# …
bar(options)
end
def bar(options = {})
puts options.fetch(:name, ‘unknown’) # => 'unknown'
end
使用Ruby 2.0命名参数:
def foo(name: nil)
# …
bar(name: name)
end
def bar(name: ‘unknown’)
# …
puts name # => nil, since nil is explicitly passed from `foo`
end
答案 0 :(得分:6)
可能最好的方法是:
def bar(name: nil)
name ||= 'unknown'
puts name
end
答案 1 :(得分:1)
目前尚不清楚为什么要知道是否提供了论证。最有用的理由是,您需要一个可选参数。如果这是原因,那么从Ruby 2.1开始,你可以得到你想要的东西。
def foo(a:,b:nil,c:3)
[a, b, c]
end
foo a: 1, b: 2, c: 3
#=> [1, 2, 3]
foo a: 1, b: 2
#=> [1, 2, 3]
foo a: 1
#=> [1, nil, 3]
foo
#ArgumentError: missing keyword: a
答案 2 :(得分:1)
您可以使用“未定义”值作为默认值,以区别于nil:
Undefined = Object.new.freeze
def foo(a: Undefined)
puts a
end
foo(a: nil) # => "nil"
foo # => "#<Object:0x000056004b29a058>"
如果您使用dry-rb,则可以使用Dry::Core::Constants::Undefined
(source),它提供了一些附加功能:
Undefined = Dry::Core::Constants::Undefined
def foo(a: Undefined)
puts a
end
foo(a: nil) # => "nil"
foo # => "Undefined"
答案 3 :(得分:0)
我假设你的例子中你没有在name
中使用foo
但想要传递它。
您应该将catch all用于命名参数:
def foo(**named)
# …
bar(**named)
end
def bar(name: ‘unknown’)
# …
puts name
end
foo # => 'unknown'
foo(name: 'baz') # => 'baz'
请注意,这不会干扰其他参数(已命名或未命名),因此如果您有foo
的其他参数:
def foo(what, other: 42, **named)