Это плохая форма использовать экземпляры VAR непосредственно в ruby? - PullRequest
1 голос
/ 02 апреля 2012

Должны ли вы всегда создавать аксессоры (для чтения и / или записи) в ruby?Если у вас есть класс, который не предназначен для повторного использования снаружи, я не могу просто использовать переменные экземпляра напрямую?

Одна из проблем, с которыми я столкнулся, заключается в том, что в тестах трудно заглушить @instance_vars.

Ответы [ 3 ]

3 голосов
/ 03 апреля 2012

Переменные экземпляра не имеют значения, когда дело доходит до тестирования. Вам следует проверить свои методы , чтобы убедиться, что они дают правильные результаты.

Когда вы определяете метод считывателя для атрибута, вы открываете этот атрибут миру. Не имеет значения, является ли значение атрибута источником переменной экземпляра, базы данных, файла, вычислений во время выполнения или чего-либо еще. Люди могут просто вызвать метод, чтобы получить значение.

Точно так же, когда вы определяете метод записи для атрибута, вы даете всем знать, что они могут установить его, если это необходимо. Неважно, к чему относится значение.

Только ваши методы определяют ваш публичный API. Все остальное - деталь реализации.

В пределах вашего определения класса, конечно, нет никакого вреда в непосредственном доступе к переменным экземпляра:

@variable = :value

Нет причин вызывать методы, если вам нужны простые присваивания. Конечно, иногда вам нужны более сложные функциональные возможности. Ленивая инициализация, например:

def variable
  @variable ||= :value
end

# ...

variable.to_s

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

private :variable

Если честно, в Ruby ничего не заперто. Даже без методов установки люди могут легко вмешаться в ваш объект, если они действительно хотят:

class << (object = Object.new)
  private
  def variable; @variable end
end

object.variable
# NoMethodError: private method `variable' called

# send bypasses access control
object.send :variable
# => :value

object.instance_variables
# => [:@variable]
object.instance_variable_get :@variable
# => :value

object.instance_variables.each do |variable|
  object.instance_variable_set variable, nil
end
object.instance_variable_get :@variable
# => nil
1 голос
/ 03 апреля 2012

Переменные экземпляра предназначены для использования в контексте рассматриваемого экземпляра. Если вам нужно обмениваться данными с другими объектами или даже другими экземплярами, вы должны предоставлять им attr_reader или attr_accessor, как требуется, если вы не пишете свои собственные методы для облегчения этого.

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

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

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

Некоторые языки зашли настолько далеко, что практически невозможно напрямую изменить внутреннее состояние объекта, но в этом отношении Ruby весьма небрежен. Тем не менее, просто потому, что что-то можно сделать, не значит, что оно должно.

Когда вы определяете методы доступа, вы сами решаете, используете ли вы их в реализации этого экземпляра. Иногда удобнее обращаться к ним напрямую, вызывая @var вместо self.var, но бывают случаи, когда использование средства доступа предоставляет дополнительные функции, которых нет у переменной экземпляра. Это также может упростить рефакторинг вашего приложения, поскольку у вас есть единственная точка контроля.

1 голос
/ 02 апреля 2012

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

...