I’m still learning Ruby, and I’m curious about whether it is appropriate to use a class variable, constant, or local variable in this scenario.
我还在学习Ruby,我想知道在这个场景中使用类变量、常量或局部变量是否合适。
In my below code example (that generates random usernames out of a fixed character set), assigning @username
as an instance variable is fairly obvious. But I’m curious whether I should assign the charset as a constant or maybe a class variable. What would be the advantages of using another variable type in this scenario?
在我下面的代码示例(从一个固定的字符集生成随机的用户名)中,将@username分配为实例变量是相当明显的。但是我很好奇我应该将字符集赋值为常量还是类变量。在这个场景中使用另一个变量类型有什么好处?
In the current example, the _charset
is computed in every instance. (Do correct me if my assumption is wrong.) I also assume the computation would be shared between instances (as opposed to recomputed) as both a class variable and as a constant?
在当前示例中,每个实例都计算_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 个解决方案
#1
2
Because _charset = ('a'..'z').to_a + ('0'..'9').to_a
never changes from its definition, I'd create it as a class constant:
因为_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
3
You can make it a class variable or constant, actually this would be the same: only one instance would exist. And Ruby constants are not really constants - you can change a constant so it is really a variable, only because of its name Ruby recognizes a constant and issue a warning if you try to change it.
可以将它设置为类变量或常量,实际上这是一样的:只有一个实例存在。Ruby常量并不是真正的常量——您可以更改一个常量,因此它实际上是一个变量,只是因为它的名称Ruby识别一个常量,并在您试图更改它时发出警告。
But by declaring it as a constant and not a class variable you are documenting your aim: to have a constant value consisting of a character set, that is not designed to be changed. This will be obvious for anybody reading the code. This is what you want the character set for - so do it.
但是,通过将它声明为常量而不是类变量,您正在说明您的目标:拥有由字符集组成的常量值,而不是设计为要修改的值。这对于任何阅读代码的人来说都是显而易见的。这就是你想要的字符集-所以要这么做。
If you make it a class variable it will be a variable: so no problem if somebody tries to change. Of course if you plan on changing its value for whatever reason do it a class variable: again you will document your design.
如果你让它成为一个类变量,它就会成为一个变量,所以如果有人想要改变,没问题。当然,如果您打算更改它的值,无论出于什么原因,请使用类变量:您将再次记录您的设计。
#3
1
I think you can make it class variable as the _charset is going to be used in NewAccount class only and its value would not be changed for NewAccount's instance.
我认为可以将它设置为类变量,因为_charset将只在NewAccount类中使用,它的值不会因为NewAccount的实例而改变。
#4
1
In your example the @username would be computed once for each instance, and the _charset only computed once in your example– but the _charset is only a local variable, so it would be recomputed if you ran the method twice.
在您的示例中,对于每个实例,@用户名将被计算一次,而_charset只在您的示例中计算一次——但是_charset只是一个局部变量,因此如果您运行该方法两次,那么它将被重新计算。
What you want is what the Tin Man suggests, set it as a constant and compute it once. Using a class-varible (@@charset) could be misleading as the charset is not intended to change at any point.
你想要的是锡人的建议,把它设为常数,然后计算一次。使用类变量(@@charset)可能具有误导性,因为charset在任何时候都不打算更改。
#1
2
Because _charset = ('a'..'z').to_a + ('0'..'9').to_a
never changes from its definition, I'd create it as a class constant:
因为_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
3
You can make it a class variable or constant, actually this would be the same: only one instance would exist. And Ruby constants are not really constants - you can change a constant so it is really a variable, only because of its name Ruby recognizes a constant and issue a warning if you try to change it.
可以将它设置为类变量或常量,实际上这是一样的:只有一个实例存在。Ruby常量并不是真正的常量——您可以更改一个常量,因此它实际上是一个变量,只是因为它的名称Ruby识别一个常量,并在您试图更改它时发出警告。
But by declaring it as a constant and not a class variable you are documenting your aim: to have a constant value consisting of a character set, that is not designed to be changed. This will be obvious for anybody reading the code. This is what you want the character set for - so do it.
但是,通过将它声明为常量而不是类变量,您正在说明您的目标:拥有由字符集组成的常量值,而不是设计为要修改的值。这对于任何阅读代码的人来说都是显而易见的。这就是你想要的字符集-所以要这么做。
If you make it a class variable it will be a variable: so no problem if somebody tries to change. Of course if you plan on changing its value for whatever reason do it a class variable: again you will document your design.
如果你让它成为一个类变量,它就会成为一个变量,所以如果有人想要改变,没问题。当然,如果您打算更改它的值,无论出于什么原因,请使用类变量:您将再次记录您的设计。
#3
1
I think you can make it class variable as the _charset is going to be used in NewAccount class only and its value would not be changed for NewAccount's instance.
我认为可以将它设置为类变量,因为_charset将只在NewAccount类中使用,它的值不会因为NewAccount的实例而改变。
#4
1
In your example the @username would be computed once for each instance, and the _charset only computed once in your example– but the _charset is only a local variable, so it would be recomputed if you ran the method twice.
在您的示例中,对于每个实例,@用户名将被计算一次,而_charset只在您的示例中计算一次——但是_charset只是一个局部变量,因此如果您运行该方法两次,那么它将被重新计算。
What you want is what the Tin Man suggests, set it as a constant and compute it once. Using a class-varible (@@charset) could be misleading as the charset is not intended to change at any point.
你想要的是锡人的建议,把它设为常数,然后计算一次。使用类变量(@@charset)可能具有误导性,因为charset在任何时候都不打算更改。