操作Ruby类的默认值

时间:2016-10-18 04:18:37

标签: ruby arguments dice

当有多个默认值时,如何在不调用第一个初始化变量的情况下更改第二个初始化变量?

例如,创建一个Ruby类来返回类似于单个骰子滚动的值,其中六边骰子的默认值范围为1到6:

class Die

  def initialize(min=1, max=6)
    @min       = min
    @max       = max
  end

  def roll
    rand(@min..@max)
  end
end

如果我想使用此代码来模拟滚动20面模具的返回,我可以写下以下内容:

p Die.new(min=1, max=20).roll

...但是有没有办法只争论第二个(最大)值?

值得注意的是 - 这是我感到困惑的地方(我不完全理解Ruby类属性和变量范围) - 如果我调用:

p Die.new(max=20).roll

...我打印nil。 ?。 (我知道这是因为rand(20..6)返回nil,但我认为max=会保留第一个参数的默认最小值 - 而max=20会被提取为整数20绑定min= ......这对我来说似乎很奇怪。)

我想我可以重新使用Die类来获取边数的默认值,并设置相对于边数的最小(或最大)值,但这不是我主要问题的重点:如何只覆盖第二个默认值而不显式写第一个...

假设大多数骰子的最小值通常为1,我意识到我可以像这样颠倒min和max的顺序:

class Die2

  def initialize(max=6, min=1)
    @max       = max
    @min       = min
  end

  def roll
    rand(@min..@max)
  end  
end

...然后调用任何最大数量的边,如:

p Die2.new(20).roll

...但是考虑到class Die的语法(以及我倾向于在最大值之前写出最小值),有没有办法只输入第二个值的参数?或者,也许我接近Ruby类很差?任何帮助或指导表示赞赏 - 谢谢!

2 个答案:

答案 0 :(得分:3)

如果你写

class Die
  def initialize(min=1, max=6)
    @min, @max = min, max
  end
end

并通过传递一个参数来创建一个新实例,例如:

die = Die.new(3)
  #=> #<Die:0x007fcc6902a700 @min=3, @max=6>

我们可以从返回值中看到,参数3已分配给@min@max获取其默认值。简而言之,要将值传递给@max,您还必须将一个值传递给@min(当然,除非您反转参数的顺序)。

您可以使用Ruby v2.0中引入的命名参数(或命名参数)来执行您想要的操作。

class Die
  def initialize(min: 1, max: 6)
    @min, @max = min, max
  end
end

die = Die.new(max: 3)
  #=> #<Die:0x007fcc698ccc00 @min=1, @max=3>

(或die = Die.new(:max=>3)。如您所见,@min等于其默认值,@max等于传递的参数3

Ruby v2.0中的关键字参数需要默认值,但v2.1也扩展了它们的功能以允许所需的命名参数。例如,请参阅this article

最后,请考虑以下两种情况(第二种情况更有趣)。

class Die
  def initialize(min=1, max: 6)
    @min, @max = min, max
  end
end
die = Die.new(max: 3)
  #=> #<Die:0x007fcc69954448 @min=1, @max=3>

class Die
  def initialize(min, max: 6)
    @min, @max = min, max
  end
end
die = Die.new(max: 3)
  #=> #<Die:0x007fa01b900930 @min={:max=>3}, @max=6> 

答案 1 :(得分:2)

在Ruby 2.0及更高版本中,您可以使用关键字参数来实现相同的效果:

class Die

  def initialize(min: 1, max: 6)   #<--declare arguments like this
    @min       = min
    @max       = max
  end

  def roll
    rand(@min..@max)
  end
end

p Die.new(max: 20).roll            #<--and call like this

https://repl.it/Dyxn/0

您可以在此article

中详细了解关键字参数