开发者

What kind of Ruby variable do I want to use here?

开发者 https://www.devze.com 2023-03-02 13:30 出处:网络
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.

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.

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?

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?

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
    retur开发者_如何学JAVAn _newusername
  end

end


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.

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.


Because _charset = ('a'..'z').to_a + ('0'..'9').to_a never changes from its definition, I'd create it as a class constant:

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


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.


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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消