Оба случая в точности эквивалентны из-за запятой в строке 2: запятая означает, что вы проходите два аргумента до attr_accessor
, а не один.
Каков второй аргумент? Ну, это то, что приходит после запятой, конечно, что является выражением def
. В более старых версиях Ruby возвращаемое значение выражения определения метода было определено реализацией (в некоторых реализациях оно возвращало nil
, в некотором компилированном байт-коде метода), но в текущих версиях Ruby возвращаемое значение выражения def
стандартизован как Symbol
, обозначающий имя метода, имеющего значение def
. Таким образом, в этом случае выражение def
оценивается как :initialize
.
Теперь, потому что Рубин является строгим языком, аргументы оцениваются, прежде чем они передаются, что означает, что def initialize
оценивается первого, который определяет initialize
метод с одним параметром.
Однако сразу же после этого, attr_accessor
вызывается с двумя аргументами, :username
и :initialize
, и в результате, attr_accessor
создаст четыре метода: username=
, username
, initialize=
и initialize
, тем самым переписав метод, который мы только что определили, с одной который не имеет параметра.
Вот почему два примера одинаков: в то время как два initialize
методы отличаются изначально, они сразу перезаписаны с идентичным способом.
(я думаю, технически, вы могли наблюдать разницу, если вам удалось вызвать initialize
из другого потока в только нужное время, непосредственно после того, как она определяется в первый раз, но до его перезаписи.Это чрезвычайно крошечное окно, хотя)
Обратите внимание, что код размещен выдаст предупреждение на этот счет:.
user.rb:2: warning: method redefined; discarding old initialize
user.rb:3: warning: previous definition of initialize was here
Вы можете увидеть эффект строгой оценки аргументов здесь в строке числа: он жалуется, что этот метод перезаписывается в строке 2, но ранее был определен в строке 3, который фактически наступает после 2, но был оценен до.
Это показывает что-то, о чем я писал много раз и снова и снова: вы должны на самом деле читать предупреждения. Они были помещены туда не просто так.
Его мнение основано на вопросе, вторая версия кажется более кратким и также не требует определения 'attr_accessor' - следовательно, я предполагаю, что это более предпочтительно –