В Ruby есть удобный и удобный способ обмена переменными экземпляра с помощью таких ключей, как
attr_accessor :var
attr_reader :var
attr_writer :var
Почему я бы выбрал attr_reader
или attr_writer
если бы я мог просто использовать attr_accessor
? Есть ли что-то вроде производительности (в чем я сомневаюсь)? Я думаю, что есть причина, иначе они не сделали бы такие ключи.
Ответы:
Вы можете использовать различные средства доступа, чтобы сообщить о своем намерении кому-то, читающему ваш код, и упростить написание классов, которые будут работать правильно, независимо от того, как вызывается их публичный API.
Здесь я вижу, что могу читать и писать возраст.
Здесь я вижу, что могу читать только возраст. Представьте, что он установлен конструктором этого класса и после этого остается постоянным. Если для возраста существовал мутатор (писатель), а класс был написан, предполагая, что установленный возраст не изменится, то в результате вызова кода этим мутатором может возникнуть ошибка.
Но что происходит за кулисами?
Если вы напишите:
Это переводится на:
Если вы напишите:
Это переводится на:
Если вы напишите:
Это переводится на:
Зная это, вот еще один способ подумать об этом: если бы у вас не было помощников attr _..., и вы должны были написать аксессоры самостоятельно, вы бы написали больше аксессоров, чем требовалось вашему классу? Например, если нужно только прочитать возраст, вы бы также написали метод, позволяющий записать его?
источник
attr_reader :a
сравнению сdef a; return a; end
confreaks.net/videos/…attr_reader
определенный определитель доступа занимает 86% времени, которое делает средство доступа, определенное вручную. Для Ruby 1.9.0attr_reader
определенный аксессор занимает 94% времени, определенного вручную. Однако во всех моих тестах средства доступа работают быстро: средство доступа занимает около 820 наносекунд (Ruby 1.8.7) или 440 наносекунд (Ruby 1.9). На этих скоростях вам нужно будет вызывать метод доступа сотни миллионов раз,attr_accessor
чтобы повысить производительность и повысить общее время выполнения даже на одну секунду.attr_accessor :a, :b
Все ответы выше верны;
attr_reader
иattr_writer
удобнее писать, чем вручную вводить методы, для которых они являются сокращенными. Кроме того, они предлагают гораздо лучшую производительность, чем самостоятельное написание определения метода. Для получения дополнительной информации см. Слайд 152 из этого доклада ( PDF ) Аарона Паттерсона.источник
Не все атрибуты объекта предназначены для непосредственной установки вне класса. Наличие пишущих для всех переменных вашего экземпляра, как правило, является признаком слабой инкапсуляции и предупреждением о том, что вы вводите слишком большую связь между вашими классами.
В качестве практического примера: я написал дизайнерскую программу, в которой вы помещаете предметы в контейнеры. Элемент имел
attr_reader :container
, но предлагать писателя не имело смысла, так как контейнер элемента должен меняться только тогда, когда он помещается в новый, что также требует информации о расположении.источник
Важно понимать, что методы доступа ограничивают доступ к переменным, но не к их содержимому. В ruby, как и в некоторых других языках OO, каждая переменная является указателем на экземпляр. Так, если у вас есть атрибут к Hash, например, и вы устанавливаете его как «только для чтения», вы всегда можете изменить его содержимое, но не содержимое указателя. Посмотри на это:
Как видите, можно удалить пару ключ / значение из Hash @a, добавить новые ключи, изменить значения и так далее. Но вы не можете указать на новый объект, потому что это переменная экземпляра только для чтения.
источник
Вы не всегда хотите, чтобы переменные вашего экземпляра были полностью доступны извне класса. Есть много случаев, когда разрешение доступа на чтение к переменной экземпляра имеет смысл, но запись в него может быть невозможной (например, модель, которая извлекает данные из источника только для чтения). Бывают случаи, когда вы хотите противоположного, но я не могу вспомнить ни одного, который не был придуман над моей головой.
источник