Это зависит от того, что вы хотите сделать с полученным объектом.
Ваш вариант всегда возвращает новый объект, если значение @arr
не установлено ни в каком истинном значении. Это гарантирует, что это значение не может повлиять на состояние вашего экземпляра OptionOne
. Основное отличие от OptionThree
является поведение для этого случая:
option_one = OptionOne.new(nil)
arr = option_one.arr
arr[0] = "Hello"
arr
# => ["Hello"]
option_one.arr
# => []
против для OptionThree
:
option_three = OptionThree.new(nil)
arr = option_three.arr
arr[0] = "Hello"
arr
# => ["Hello"]
option_three.arr
# => ["Hello"]
В случае OptionThree
, единый объект массива будет сохраняться на объекте опции и таким образом изменяемый любым последующим кодом. В случае OptionOne
вы всегда возвращаете новый объект Array.
Обратите внимание, что это различие выполняется только в том случае, если @arr
не был инициализирован значением истины (например, массивом). В этом случае оба варианта показывают поведение OptionThree
. Часто вы, таким образом, видите OptionThree
, чтобы сохранить такое же поведение для всех случаев.
Если вы знаете, что хотите сохранить внутреннее состояние объекта опций во всех случаях, может возникнуть смысл возвращать новый объект каждый раз.
Теперь, чтобы OptionTwo
, это не сработает. Поскольку вы всегда устанавливаете @arr
в инициализаторе, он всегда будет установлен и, следовательно, будет возвращен. Таким образом, часть else
никогда не будет выполнена. Ваш OptionTwo
таким образом, может быть сокращен до:
def OptionTwo
def initialize(arr)
@arr = arr
end
attr_reader :arr
end
Обратите внимание, что при использовании defined?
с переменным экземпляром почти всегда плохая идея. В Ruby переменные экземпляра неявно инициализируются во многих случаях, например. при чтении в любом месте (независимо от того, было ли оно ранее задано явное значение). Таким образом, опираясь на поведение defined?
, вы должны быть очень осторожны, чтобы не случайно определить его. Часто гораздо удобнее предположить, что он определяется и обрабатывает поведение, основанное на его значении.
Если nil
и false
не являются допустимыми значениями для @arr
, вы можете всегда безопасно инициализировать его в массив с помощью ||=
. Только любое из них является допустимым значением, вы должны добавить дополнительную логику для выбора правильной инициализации.
Что вы пытаетесь сделать с линиями '@ arr'? –
В этом коде нет способа инициализировать @arr со значением, поэтому @arr всегда будет nil (не определено). Кроме того, в OptionOne # arr вам нужно сказать '@ arr' (обратите внимание на '@'). В противном случае функция вызовет себя до тех пор, пока вы не получите переполнение стека. –
Если это просто пустой массив, с которым вы инициализируете переменную, почему бы не выполнить инициализацию в конструкторе и избежать необходимости в этом? Величина ленивой инициализации (инициализация отсрочки до ее появления) возникает, когда инициализация является дорогостоящей (во времени, в памяти, других ресурсах и т. Д.). –