我想创建一个需要值的函数,除非它已经创建了一个实例值。但是,我不希望默认情况下创建参数nil
,而是希望它优雅地知道它是否需要接受参数。例如,
def config(c)
@config ||= c
end
如果我调用它,将返回@config
,但当我尝试在没有参数的情况下调用它时,它将给出ArgumentError
。我可以使函数不需要参数是实例变量存在吗?
答案 0 :(得分:9)
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
。也就是说,至少在你的基本例子中,这是最惯用的方式。
答案 1 :(得分:3)
我不确定为什么你需要避免将参数默认为nil,而是要获得你指定的功能:
'如果没有传入参数并且未设置实例变量,则需要引发Argument错误,但如果设置了实例变量,则允许在没有参数的情况下调用它。'
这将有效:
def config(c=nil)
raise ArgumentError if c.nil? && @config.nil?
@config ||= c
end
是的,我将参数默认为nil,你要求避免,但如果参数为nil那么我们就会短路并在没有设置@config时引发错误,如果设置了@config,它就不会无论参数是否为零,因为下一行只返回@config。
答案 2 :(得分:-1)
您可以在参数前使用*
:
def config(*c)
@config ||= c
end
但是请注意,如果您运行c
,您将获得config('hi', 'hello')
的多个值,除此之外它还可以。