我想在这里使用什么样的Ruby变量?

时间:2011-04-30 19:55:32

标签: ruby constants scope instance-variables local-variables

我还在学习Ruby,我很好奇在这种情况下是否适合使用类变量,常量或局部变量。

在我的下面的代码示例中(从固定字符集中生成随机用户名),将@username指定为实例变量是相当明显的。但我很好奇我是否应该将charset指定为常量或类变量。在这种情况下使用另一种变量类型有什么好处?

在当前示例中,_charset在每个实例中计算。 (如果我的假设是错误的,请纠正我。)我还假设计算将在实例之间共享(而不是重新计算)作为类变量和常量?

class NewAccount

  def initialize
    @username = self.generate_username
  end

  def generate_username
    _charset = ('a'..'z').to_a + ('0'..'9').to_a
    _newusername = Array.new(20) { _charset[rand(_charset.length)] }.join
    return _newusername
  end

end

4 个答案:

答案 0 :(得分:3)

你可以使它成为一个类变量或常量,实际上这是相同的:只存在一个实例。并且Ruby常量不是真正的常量 - 你可以改变一个常量,因此它实际上是一个变量,只是因为它的名字Ruby识别一个常量并在你试图改变它时发出警告。

但是通过将它声明为常量而不是类变量,您正在记录您的目标:具有由字符集组成的常量值,该字符集不是为了更改而设计的。对于阅读代码的任何人来说,这都是显而易见的。这就是你想要的字符集 - 所以就这样做。

如果你把它变成一个类变量,它将是一个变量:所以如果有人试图改变就没问题。当然,如果您打算因任何原因改变其值,请将其作为类变量:再次,您将记录您的设计。

答案 1 :(得分:2)

因为_charset = ('a'..'z').to_a + ('0'..'9').to_a永远不会改变它的定义,所以我将它创建为类常量:

class NewAccount

  CHARSET = ('a'..'z').to_a + ('0'..'9').to_a

  def initialize
    @username = self.generate_username
  end

  def generate_username
    _newusername = Array.new(20) { CHARSET[rand(CHARSET.length)] }.join
    return _newusername
  end

end

答案 2 :(得分:1)

我认为你可以使它成为类变量,因为_charset将仅用于NewAccount类,并且不会为NewAccount的实例更改其值。

答案 3 :(得分:1)

在您的示例中,@ username将为每个实例计算一次,而_charset仅在您的示例中计算一次 - 但_charset只是一个局部变量,因此如果您运行该方法两次,它将被重新计算。

你想要的是 建议的内容,将其设置为常量并计算一次。使用class-varible(@@ charset)可能会产生误导,因为charset不会在任何时候发生变化。