Какую переменную Ruby я хочу использовать здесь? - PullRequest
2 голосов
/ 30 апреля 2011

Я все еще изучаю Ruby, и мне интересно, уместно ли использовать переменную класса, константу или локальную переменную в этом сценарии.

В моем примере кода ниже (который генерирует случайныйимена пользователей из фиксированного набора символов), назначение @username в качестве переменной экземпляра довольно очевидно.Но мне любопытно , должен ли я назначить набор символов как константу или, может быть, переменную класса .Каковы будут преимущества использования другого типа переменной в этом сценарии?

В текущем примере _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 ]

3 голосов
/ 01 мая 2011

Вы можете сделать его переменной класса или константой, фактически это будет то же самое: будет существовать только один экземпляр. А константы Ruby на самом деле не являются константами - вы можете изменить константу, чтобы она действительно была переменной, только потому, что ее имя Ruby распознает константу и выдает предупреждение, если вы пытаетесь ее изменить.

Но, объявив ее как константу, а не переменную класса, вы документируете свою цель: иметь постоянное значение, состоящее из набора символов, которое не предназначено для изменения. Это будет очевидно для любого, кто читает код. Это то, для чего вы хотите набор символов - так и сделайте.

Если вы сделаете его переменной класса, это будет переменная, так что нет проблем, если кто-то попытается измениться. Конечно, если вы планируете изменить его значение по какой-либо причине, сделайте это переменной класса: снова вы задокументируете свой дизайн.

2 голосов
/ 01 мая 2011

Поскольку _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
1 голос
/ 01 мая 2011

В вашем примере @username будет вычисляться один раз для каждого экземпляра, а _charset вычисляется только один раз в вашем примере - но _charset является только локальной переменной, поэтому он будет пересчитан, если вы запустите метод дважды.

То, что вы хотите, - это то, что оловянный человек предлагает, задайте как константу и вычислите ее один раз. Использование class-varible (@@ charset) может ввести в заблуждение, так как charset не предназначен для изменения в любой точке.

1 голос
/ 01 мая 2011

Я думаю, вы можете сделать его переменной класса, так как _charset будет использоваться только в классе NewAccount, и его значение не будет изменено для экземпляра NewAccount.

...