仅接受nil参数是设置实例变量

时间:2013-07-10 02:20:22

标签: ruby

我想创建一个需要值的函数,除非它已经创建了一个实例值。但是,我不希望默认情况下创建参数nil,而是希望它优雅地知道它是否需要接受参数。例如,

def config(c)
    @config ||= c
end
如果我调用它,

将返回@config,但当我尝试在没有参数的情况下调用它时,它将给出ArgumentError。我可以使函数不需要参数是实例变量存在吗?

3 个答案:

答案 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')的多个值,除此之外它还可以。