@MisterMK

Self или @ для атрибута класса?

Доброго времени суток!
По текущему вопросы было прочитано куча статей и был перерыт весь гугл вкупе с Ruby Way, но конкретно я так и не понял - что к чему.
Вопрос в следующем:
Насколько будет правильным или же неправильным использование self в методе initialize для атрибутов класса?
И будет ли нарушением, если, скажем, мы будем ставить "@" перед атрибутами, а не self?
Судя по всему изученному и прочитанному, я делаю вывод, что ставить нужно self, ибо мы вызываем метод, а не обращаемся к самой переменной. Соответственно, "@" нужно ставить при обращении к переменной как к get'теру, а не как к set'теру.
Прошу рассудить.
Заранее, благодарю!

class Log_parse
  attr_accessor :dir, :input_filename, :output_filename, :result_filename,
                  :src_ip_final_table, :dst_ip_final_table, 
                  :proto_final_table, :service_port_final_table

  def initialize
    self.dir = ""                
    self.output_filename = []
    self.input_filename = 
    [
      '01_02_2019.txt', '05_02_2019.txt', 
      '07_02_2019.txt', '09_02_2019.txt', 
      '11_02_2019.txt', '13_02_2019.txt',
      '15_02_2019.txt', '18_02_2019.txt', 
      '20_02_2019.txt', '21_02_2019.txt', 
      '24_02_2019.txt', '26_02_2019.txt',
      '28_02_2019.txt'
    ]
    @input_filename.each_with_index do |filename, iterator|
      self.output_filename[iterator] = @dir + 'output_' + filename
    end

    self.src_ip_final_table = []
    self.dst_ip_final_table = []
    self.proto_final_table = []
    self.service_port_final_table = []
  end
# ...
end
  • Вопрос задан
  • 170 просмотров
Пригласить эксперта
Ответы на вопрос 2
oh_shi
@oh_shi
Это одно и тоже. self.dir = вызывает dir=, который вы создали, когда указали attr_accessor :dir, выглядит это как-то так:
def dir=(str)
  @dir = str
end

Потому логично использовать напрямую @, еще и на 4 символа короче=)
Плюс @ что его можно использовать и без attr_accessor. Но если нужны геттер и сеттер, то лучше использовать attr_accessor, чем писать их самому, потому что ваш код будет на руби, а attr_accessor написан на С.
Ответ написан
c3gdlk
@c3gdlk
Ментор в http://rubyboost.ru/
Ваш простой вопрос не так прост, как кажется.

Недостаток инстанс переменных в том, что по умолчанию они имеют значение nil и поэтому возможно пропустить опечатку. К этому многие приходят, потому что рано или поздно пишут код, в котором для инстанс переменной допустимо значение nil, а оно там всегда nil из-за опечатки. Инстанс переменные хороши для мемоизации, но их использование лучше сократить до минимума.

В данном случае нет идеального решения, потому что в руби нельзя объявить приватный setter.

Т.е. в следующем коде

class Log_parse
  attr_accessor :dir

  def initialize
    self.dir = "" 
  end
end


руби не поймет, что вы из одного и того же класса вызываете сеттер. self считается объектом, а вызов через точку - вызовом публичного метода. Идеальный вариантом был бы случай, когда вы отдельно определяете отдельно публичные аксессоры, отдельно приватные и пользуетесь только аксессорами, но в руби так сделать нельзя (без костылей по крайней мере).

В итоге совет следующий:
В остальных методах класса использовать только аксессоры - публичные или приватные.
В конструкторе уже возможны варианты. Если вы считаете, что объявление публичных аксессоров никак не навредит классу, лучше использовать аксессоры. Иначе - инстанс переменные.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы