我想创建一个需要值的函数,除非它已经创建了一个实例值。但是,我不想nil
默认设置参数,而是希望它优雅地知道它是否需要接受参数。例如,
def config(c)
@config ||= c
end
@config
如果我调用它会返回,但是ArgumentError
当我尝试在没有参数的情况下调用它时会给出。如果实例变量存在,我可以使函数不需要参数吗?
我想创建一个需要值的函数,除非它已经创建了一个实例值。但是,我不想nil
默认设置参数,而是希望它优雅地知道它是否需要接受参数。例如,
def config(c)
@config ||= c
end
@config
如果我调用它会返回,但是ArgumentError
当我尝试在没有参数的情况下调用它时会给出。如果实例变量存在,我可以使函数不需要参数吗?
Ruby 没有提供任何工具来做到这一点,但为什么不自己提出 ArgumentError 像这样:
def config(c = nil)
raise ArgumentError unless c || @config
@config ||= c
end
或者,Ruby 2.0 提供了类似这样的关键字参数:
class A
def config c: (@config or raise ArgumentError)
@config = c
end
end
a = A.new
a.config #=> ArgumentError
a.config(c: 2) #=> 2
a.config #=> 2
当然,也许您真正应该做的只是使用正常的设置方法(即def config=(value) ...
)或简单地使用attr_accessor :config
. 也就是说,至少在您的基本示例中,这是最惯用的方法。
我不确定为什么您需要避免将参数默认为 nil,但要获得您指定的功能:
“如果没有传入参数并且未设置实例变量,则需要引发参数错误,但如果设置了实例变量,则允许在没有参数的情况下调用它。”
这将起作用:
def config(c=nil)
raise ArgumentError if c.nil? && @config.nil?
@config ||= c
end
是的,我将参数默认为 nil,这是您要求避免的,但如果参数为 nil,那么如果未设置 @config 并且如果设置了 @config,则我们会短路并引发错误,如果参数为 nil,因为下一行将只返回 @config。
您可以*
在参数之前使用:
def config(*c)
@config ||= c
end
但是请注意,c
如果您运行,您现在将获得多个值:config('hi', 'hello')
除此之外它还可以工作。