Работает ли attr_accessor таким же образом в Git? Я обнаружил, что некоторые учебные пособия не объясняют достаточно, а другие предполагают предварительные знания.
Angelfirenze
10
@Angelfirenze, не gitимеет ничего общего с attr_accessor. Git представляет собой программное обеспечение управления версиями, в то время как attr_accessorэто метод Рубин .
Узбекджон
Ответы:
2360
Допустим, у вас есть класс Person.
classPersonend
person =Person.new
person.name # => no method error
Очевидно, мы никогда не определяли метод name. Давайте сделаем это.
classPersondef name
@name# simply returning an instance variable @nameendend
person =Person.new
person.name # => nil
person.name ="Dennis"# => no method error
Ага, мы можем прочитать имя, но это не значит, что мы можем присвоить имя. Это два разных метода. Первый называется читателем, а второй - писателем . Мы еще не создали писателя, поэтому давайте сделаем это.
classPersondef name
@nameenddef name=(str)@name= str
endend
person =Person.new
person.name ='Dennis'
person.name # => "Dennis"
Потрясающие. Теперь мы можем писать и читать переменные экземпляра, @nameиспользуя методы чтения и записи. Кроме того, это делается так часто, зачем тратить время на написание этих методов каждый раз? Мы можем сделать это проще.
classPerson
attr_reader :name
attr_writer :name
end
Даже это может стать повторяющимся. Когда вы хотите, чтобы читатель и писатель просто использовали аксессор!
classPerson
attr_accessor :name
end
person =Person.new
person.name ="Dennis"
person.name # => "Dennis"
Работает так же! И угадайте, что: переменная экземпляра @nameв нашем объекте person будет установлена точно так же, как когда мы делали это вручную, так что вы можете использовать ее в других методах.
Вот и все. Для того , чтобы понять , как attr_reader, attr_writer, и attr_accessorметоды на самом деле генерировать методы для вас, читать другие ответы, книги, рубин документы.
@hakunin - спасибо за этот четкий ответ. Чего мне не хватает, так это того, почему синтаксис Ruby предлагает использовать двоеточие ':' для переменных экземпляра в выражении attr_ *? Кажется, что было бы более простым использовать тот же синтаксис «@», который используется в других местах класса для ссылки на переменную.
Будет
207
@WilliamSmith Чтобы ответить на ваш вопрос, вы должны понимать, что attr_accessorэто метод, вызываемый в текущем классе, и :nameпараметр, передаваемый этому методу. Это не специальный синтаксис, это простой вызов метода. Если бы вы @nameуказали переменную, это не имело бы смысла, потому что @name содержало бы nil. Так что это было бы как писать attr_accessor nil. Вы не передаете ему переменную, которую нужно создать, вы передаете имя, которое хотите, чтобы переменная была вызвана.
Макс Черняк
23
@hakunin - Это имеет смысл. Я только сегодня узнал, что ruby на самом деле «работает», когда он анализирует файл, и что каждое выражение и выражение на самом деле являются вызовом метода для некоторого объекта. Включая attr_accessor. Очень полезно.
Будет
52
3 года пользовался Rails, даже не знал этого. Позор
Шон Сяо
5
@Buminda да, но метод nameи переменная @nameне одно и то же. Не путай их. У вас есть переменная экземпляра @nameв вашем классе, и вы определяете, attr_reader :nameчтобы иметь возможность читать ее извне. Без attr_readerэтого нет простого способа получить доступ @nameза пределами вашего класса.
Макс Черняк
127
attr_accessor - это просто метод . (Ссылка должна дать более глубокое представление о том, как она работает - посмотрите на сгенерированные пары методов, и учебник должен показать вам, как ее использовать.)
Хитрость в том, что classэто не определение в Ruby (это «просто определение» в таких языках, как C ++ и Java), но это выражение, которое оценивает . Именно во время этой оценки attr_accessorвызывается метод, который, в свою очередь, изменяет текущий класс - запомните неявный получатель:, self.attr_accessorгде selfнаходится «открытый» объект класса в этой точке.
Потребность attr_accessorи в друзьях, ну и
Ruby, как и Smalltalk, не разрешает доступ к переменным экземпляра вне методов 1 для этого объекта. То есть переменные экземпляра не могут быть доступны в x.yформе, как это принято в, скажем, Java или даже Python. В Ruby yвсегда принимается сообщение для отправки (или «метод для вызова»). Таким образом, attr_*методы создают оболочки, которые обеспечивают @variableдоступ к экземпляру через динамически создаваемые методы.
Котел отстой
Надеюсь, что это проясняет некоторые мелочи. Удачного кодирования.
1 Это не совсем верно, и в этом есть некоторые «методы» , но нет синтаксической поддержки доступа к «общедоступным переменным экземпляра».
Когда вы говорите, что attr_accessor - это «просто метод», я получаю это. Но какой синтаксис используется для вызова этого метода? У меня возникают проблемы с поиском раздела в документации по ruby, в котором говорится о синтаксисе: some_method: name => "what",: notherName,: etc
BT
69
attr_accessorявляется (как указано @pst) просто методом. Что он делает, так это создает больше методов для вас.
Итак, этот код здесь:
classFoo
attr_accessor :bar
end
эквивалентно этому коду:
classFoodef bar
@barenddef bar=( new_value )@bar= new_value
endend
Вы можете написать этот метод самостоятельно в Ruby:
classModuledef var( method_name )
inst_variable_name ="@#{method_name}".to_sym
define_method method_name do
instance_variable_get inst_variable_name
end
define_method "#{method_name}="do|new_value|
instance_variable_set inst_variable_name, new_value
endendendclassFoo
var :bar
end
f =Foo.new
p f.bar #=> nil
f.bar =42
p f.bar #=> 42
Это отличный пример использования метапрограммирования даже в сценариях самого начального уровня. Очень хорошо.
Джон Саймон
2
Я искал эскиз реализации attr_accessorи нашел здесь, наконец! Хотя это решило мою проблему, но мне любопытно узнать, где (книга / официальный документ) я могу найти пример реализации, подобный этому?
Васиф Хоссейн
40
attr_accessor очень просто:
attr_accessor :foo
это ярлык для:
def foo=(val)@foo= val
enddef foo
@fooend
это не что иное, как получатель / установщик объекта
ваш ответ в порядке. Согласно моему словарю, «ярлык» означает «более короткий альтернативный маршрут», а не «синтаксический сахар» или «макрос, интерпретируемый интерпретатором».
Bowsersenior
25
По сути, они подделывают общедоступные атрибуты данных, которых нет в Ruby.
Хотя этот комментарий не совсем полезен, это правда. Подчеркивает тот факт, что общедоступные атрибуты данных не существуют вне методов get в Ruby, что является действительно полезной информацией для тех, кто пытается изучать язык.
Эрик Дэнд
3
Это действительно не должно быть опущено. Как не-Ruby парень, пытающийся выяснить это, этот ответ очень полезен!
Брэд
1
Согласен, похоже, очень похоже на имя C # {get; set;}
Дэвид Милер
17
Это просто метод, который определяет методы получения и установки для переменных экземпляра. Примером реализации будет:
defself.attr_accessor(*names)
names.each do|name|
define_method(name){instance_variable_get("@#{name}")}# This is the getter
define_method("#{name}="){|arg| instance_variable_set("@#{name}", arg)}# This is the setterendend
обработка нескольких атрибутов таким способом - это здорово!
Васиф Хоссейн
Это был действительно полезный фрагмент кода для решения другого вопроса, который я имел отношение к метапрограммированию.
alexventuraio
15
Простое объяснение без кода
Большинство из приведенных выше ответов используют код. Это объяснение пытается ответить на него, не используя ничего, по аналогии / истории:
Внешние стороны не могут получить доступ к внутренним секретам ЦРУ
Давайте представим себе действительно секретное место: ЦРУ. Никто не знает, что происходит в ЦРУ, кроме людей внутри ЦРУ. Другими словами, внешние люди не могут получить доступ к какой-либо информации в ЦРУ. Но поскольку организация, которая является полностью секретной, бесполезна, определенная информация становится доступной внешнему миру - только то, о чем ЦРУ хочет, чтобы все знали, конечно: например, директор ЦРУ, насколько экологически безвреден этот отдел ко всем другим правительственным ведомствам и т. д. Другая информация: например, кто является его тайными оперативниками в Ираке или Афганистане - такие вещи, вероятно, останутся секретом в течение следующих 150 лет.
Если вы находитесь за пределами ЦРУ, вы можете получить доступ только к той информации, которую он предоставил общественности. Или на языке ЦРУ вы можете получить доступ только к информации, которая «очищена».
Информация, которую ЦРУ хочет сделать доступной для широкой публики за пределами ЦРУ, называется: атрибуты.
Значение атрибутов read и write:
В случае с ЦРУ большинство атрибутов «только для чтения». Это означает , что если вы являетесь участником внешней ЦРУ, вы можете спросить: «кто является директором ЦРУ?» и вы получите прямой ответ. Но что вы не можете сделать с атрибутами «только для чтения», так это вносить изменения в CIA. например, вы не можете позвонить и вдруг решите, что хотите, чтобы Ким Кардашьян был директором, или что вы хотите, чтобы Пэрис Хилтон была главнокомандующим.
Если атрибуты предоставили вам доступ для «записи», тогда вы можете вносить изменения, если хотите, даже если вы были снаружи. В противном случае, единственное, что вы можете сделать, это прочитать.
Другими словами, средства доступа позволяют вам делать запросы или вносить изменения в организации, которые в противном случае не допускают внешних сотрудников, в зависимости от того, являются ли средства доступа доступными для чтения или записи.
Объекты внутри класса могут легко получить доступ друг к другу
С другой, если вы уже были в ЦРУ, то вы могли бы легко вызвать ваш сотрудник ЦРУ в Кабуле , так как эта информация легко доступна давшая вам уже внутри. Но если вы находитесь за пределами ЦРУ, вам просто не будет предоставлен доступ: вы не сможете узнать, кто они (доступ для чтения), и вы не сможете изменить их миссию (доступ для записи).
Точно то же самое с классами и вашей возможностью доступа к переменным, свойствам и методам внутри них. НТН! Любые вопросы, пожалуйста, задавайте, и я надеюсь, что смогу уточнить.
Ваше объяснение имеет смысл! +1 Извините, вы уверены, что выражение «информация, которая очищена ЦРУ, верно?»
kouty
в ЦРУ существуют различные уровни «разрешения»: например, «Совершенно секретно» (никто, кроме «Преза») или общественное доверие (каждый может прочитать эту информацию). ЦРУ на самом деле предоставляет много очень интересных фактов!
BKSpurgeon
Вы заслуживаете повышения только для примеров Кардашьян, Пэрис Хилтон :) Я думал, что это было достаточно плохо с Трампом для президента, представьте, что эти двое отвечают за Боже!
rmcsharry
Да! Вот что нам нужно, StackOverflow без кода! :-)
Марвин
13
Если вы знакомы с концепцией ООП, вы должны быть знакомы с методами получения и установки. attr_accessor делает то же самое в Ruby.
Геттер и сеттер в общем пути
classPersondef name
@nameenddef name=(str)@name= str
endend
person =Person.new
person.name ='Eshaan'
person.name # => "Eshaan"
Сеттер Метод
def name=(val)@name= val
end
Метод получения
def name
@nameend
Метод получения и установки в Ruby
classPerson
attr_accessor :name
end
person =Person.new
person.name ="Eshaan"
person.name # => "Eshaan"
идеальное объяснение! Это очень удобное поведение, и его можно слишком легко переопределить.
Rubyrider
12
Я тоже столкнулся с этой проблемой и написал довольно длинный ответ на этот вопрос. На этот счет уже есть несколько отличных ответов, но всем, кто ищет уточнения, я надеюсь, что мой ответ поможет
Метод инициализации
Initialize позволяет вам устанавливать данные для экземпляра объекта при создании экземпляра, а не устанавливать их в отдельной строке кода каждый раз, когда вы создаете новый экземпляр класса.
classPersondef initialize(name)@name= name
enddef greeting
"Hello #{@name}"endend
person =Person.new("Denis")
puts person.greeting
В приведенном выше коде мы устанавливаем имя «Denis» с помощью метода initialize, передавая Dennis через параметр в Initialize. Если бы мы хотели установить имя без метода инициализации, мы могли бы сделать это так:
В приведенном выше коде мы устанавливаем имя, вызывая метод установщика attr_accessor с использованием person.name, а не устанавливая значения при инициализации объекта.
Оба «метода» выполнения этой работы, но инициализация экономят нам время и строки кода.
Это единственная работа по инициализации. Вы не можете вызвать инициализацию как метод. Чтобы фактически получить значения объекта экземпляра, вам нужно использовать методы получения и установки (attr_reader (get), attr_writer (set) и attr_accessor (оба)). Смотрите ниже для более подробной информации о них.
В приведенном выше коде вы вызываете методы «item_name» и «amount» в экземпляре Item «example». «Put example.item_name» и «example.quantity» вернут (или «получат») значение для параметров, которые были переданы в «example», и отобразят их на экране.
К счастью, в Ruby есть собственный метод, который позволяет нам писать этот код более кратко; метод attr_reader. Смотрите код ниже;
Этот синтаксис работает точно так же, только он экономит нам шесть строк кода. Представьте, если бы у вас было еще 5 состояний, относящихся к классу Item? Код станет длинным быстро.
Сеттеры, attr_writer: Сначала меня поразили методы сеттера: мне показалось, что он выполняет функцию, идентичную методу инициализации. Ниже я объясняю разницу на основе моего понимания;
Как указывалось выше, метод initialize позволяет вам устанавливать значения для экземпляра объекта при создании объекта.
Но что, если вы хотите установить значения позже, после создания экземпляра или изменить их после их инициализации? Это будет сценарий, в котором вы будете использовать метод установки. ЭТО РАЗНИЦА. Вам не нужно «устанавливать» определенное состояние, когда вы изначально используете метод attr_writer.
Приведенный ниже код является примером использования метода установки для объявления значения item_name для этого экземпляра класса Item. Обратите внимание, что мы продолжаем использовать метод getter attr_reader, чтобы мы могли получать значения и выводить их на экран, на тот случай, если вы захотите протестировать код самостоятельно.
Приведенный ниже код является повторением приведенного выше примера инициализации, где мы используем инициализацию для установки значения объектов item_name при создании.
Я думаю, что часть того, что смущает новых Rubyists / программистов (таких как я):
«Почему я не могу просто сказать экземпляру, что у него есть какой-либо заданный атрибут (например, имя), и присвоить этому атрибуту значение одним махом?»
Немного более обобщенно, но вот как это у меня получилось:
Данный:
classPersonend
Мы не определили Person как нечто, что может иметь имя или любые другие атрибуты в этом отношении.
Итак, если мы тогда:
baby =Person.new
... и попытаться дать им имя ...
baby.name ="Ruth"
Мы получаем ошибку, потому что в Rubyland класс объекта Person не является чем-то, что связано или способно иметь «имя» ... пока!
НО мы можем использовать любой из данных методов (см. Предыдущие ответы) как способ сказать: «Экземпляр класса Person ( baby) теперь может иметь атрибут с именем« name », поэтому у нас есть не только синтаксический способ получения и установить это имя, но для нас имеет смысл сделать это ".
Опять же, задание этого вопроса с немного другой и более общей точки зрения, но я надеюсь, что это поможет следующему экземпляру класса Person, который найдет свой путь к этой теме.
ownerи balanceтехнически не метод , а атрибут. Класс BankAccount не имеет def ownerи def balance. Если это так, то вы можете использовать две команды ниже. Но этих двух методов нет. Однако вы можете обращаться к атрибутам так, как если бы вы обращались к методу через attr_accessor!! Отсюда и словоattr_accessor . Атрибут. Accessor. Он обращается к атрибутам, как если бы вы обращались к методу.
Добавление attr_accessor :balance, :ownerпозволяет читать и писать balanceи owner«метод». Теперь вы можете использовать последние 2 метода.
Определяет именованный атрибут для этого модуля, где имя - это symbol.id2name, создавая переменную экземпляра (@name) и соответствующий метод доступа для его чтения. Также создает метод с именем name = для установки атрибута.
Я новичок в ruby и должен был просто разобраться в следующей странности. Может помочь кому-то еще в будущем. В конце концов, как было упомянуто выше, обе функции (def myvar, def myvar =) обе неявно получают доступ к @myvar, но эти методы могут быть переопределены локальными объявлениями.
classFoo
attr_accessor 'myvar'def initialize
@myvar="A"
myvar ="B"
puts @myvar# A
puts myvar # B - myvar declared above overrides myvar methodenddef test
puts @myvar# A
puts myvar # A - coming from myvar accessor
myvar ="C"# local myvar overrides accessor
puts @myvar# A
puts myvar # C
send "myvar=","E"# not running "myvar =", but instead calls setter for @myvar
puts @myvar# E
puts myvar # Cendend
Атрибуты являются компонентами класса, к которым можно получить доступ снаружи объекта. Они известны как свойства во многих других языках программирования. Их значения доступны с помощью «точечной нотации», как в object_name.attribute_name. В отличие от Python и некоторых других языков, Ruby не позволяет обращаться к переменным экземпляра напрямую из-за пределов объекта.
classCardef initialize
@wheels=4# This is an instance variableendend
c =Car.new
c.wheels # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>
В приведенном выше примере c является экземпляром (объектом) класса Car. Мы безуспешно пытались прочитать значение переменной экземпляра колеса снаружи объекта. Случилось так, что Ruby попытался вызвать метод с именем wheel внутри объекта c, но такой метод не был определен. Короче говоря, object_name.attribute_name пытается вызвать метод с именем attribute_name внутри объекта. Чтобы получить доступ к значению переменной wheel извне, нам нужно реализовать метод экземпляра с таким именем, который будет возвращать значение этой переменной при вызове. Это называется методом доступа. В общем контексте программирования обычным способом доступа к переменной экземпляра вне объекта является реализация методов доступа, также известных как методы получения и установки.
В следующем примере мы добавили методы getter и setter в класс Car, чтобы получить доступ к переменной wheel снаружи объекта. Это не «Рубиновый способ» определения методов получения и установки; он служит только для иллюстрации того, что делают методы getter и setter.
classCardef wheels # getter method@wheelsenddef wheels=(val)# setter method@wheels= val
endend
f =Car.new
f.wheels =4# The setter method was invoked
f.wheels # The getter method was invoked# Output: => 4
Приведенный выше пример работает, и аналогичный код обычно используется для создания методов получения и установки на других языках. Тем не менее, Ruby предоставляет более простой способ сделать это: три встроенных метода, называемые attr_reader, attr_writer и attr_acessor. Метод attr_reader делает переменную экземпляра доступной для чтения извне, attr_writer делает ее доступной для записи, а attr_acessor делает ее читаемой и доступной для записи.
Приведенный выше пример можно переписать так.
classCar
attr_accessor :wheels
end
f =Car.new
f.wheels =4
f.wheels # Output: => 4
В приведенном выше примере атрибут колеса будет доступен для чтения и записи извне объекта. Если бы вместо attr_accessor мы использовали attr_reader, он был бы доступен только для чтения. Если бы мы использовали attr_writer, он был бы только для записи. Эти три метода сами по себе не являются методами получения и установки, но при вызове они создают методы получения и установки для нас. Это методы, которые динамически (программно) генерируют другие методы; это называется метапрограммирование.
Первый (более длинный) пример, в котором не используются встроенные методы Ruby, следует использовать только тогда, когда в методах get и set требуется дополнительный код. Например, методу установки может потребоваться проверить данные или выполнить некоторые вычисления, прежде чем присваивать значение переменной экземпляра.
Доступ к переменным экземпляра (чтение и запись) возможен извне объекта с помощью встроенных методов instance_variable_get и instance_variable_set. Тем не менее, это редко оправдано и, как правило, является плохой идеей, поскольку обход инкапсуляции имеет тенденцию вызывать всевозможные разрушения.
Основная функциональность attr_accessor по сравнению с другими - это возможность доступа к данным из других файлов.
Так что обычно у вас есть attr_reader или attr_writer, но хорошая новость в том, что Ruby позволяет вам объединить эти два вместе с attr_accessor. Я думаю, что это мой метод go, потому что он более округлый или универсальный. Кроме того, имейте в виду, что в Rails это устранено, потому что оно делает это за вас в бэкэнде. Другими словами: вам лучше использовать attr_acessor по сравнению с двумя другими, потому что вам не нужно беспокоиться о том, чтобы быть конкретным, аксессор покрывает все это. Я знаю, что это скорее общее объяснение, но оно помогло мне как новичку.
git
имеет ничего общего сattr_accessor
. Git представляет собой программное обеспечение управления версиями, в то время какattr_accessor
это метод Рубин .Ответы:
Допустим, у вас есть класс
Person
.Очевидно, мы никогда не определяли метод
name
. Давайте сделаем это.Ага, мы можем прочитать имя, но это не значит, что мы можем присвоить имя. Это два разных метода. Первый называется читателем, а второй - писателем . Мы еще не создали писателя, поэтому давайте сделаем это.
Потрясающие. Теперь мы можем писать и читать переменные экземпляра,
@name
используя методы чтения и записи. Кроме того, это делается так часто, зачем тратить время на написание этих методов каждый раз? Мы можем сделать это проще.Даже это может стать повторяющимся. Когда вы хотите, чтобы читатель и писатель просто использовали аксессор!
Работает так же! И угадайте, что: переменная экземпляра
@name
в нашем объекте person будет установлена точно так же, как когда мы делали это вручную, так что вы можете использовать ее в других методах.Вот и все. Для того , чтобы понять , как
attr_reader
,attr_writer
, иattr_accessor
методы на самом деле генерировать методы для вас, читать другие ответы, книги, рубин документы.источник
attr_accessor
это метод, вызываемый в текущем классе, и:name
параметр, передаваемый этому методу. Это не специальный синтаксис, это простой вызов метода. Если бы вы@name
указали переменную, это не имело бы смысла, потому что @name содержало быnil
. Так что это было бы как писатьattr_accessor nil
. Вы не передаете ему переменную, которую нужно создать, вы передаете имя, которое хотите, чтобы переменная была вызвана.name
и переменная@name
не одно и то же. Не путай их. У вас есть переменная экземпляра@name
в вашем классе, и вы определяете,attr_reader :name
чтобы иметь возможность читать ее извне. Безattr_reader
этого нет простого способа получить доступ@name
за пределами вашего класса.attr_accessor - это просто метод . (Ссылка должна дать более глубокое представление о том, как она работает - посмотрите на сгенерированные пары методов, и учебник должен показать вам, как ее использовать.)
Хитрость в том, что
class
это не определение в Ruby (это «просто определение» в таких языках, как C ++ и Java), но это выражение, которое оценивает . Именно во время этой оценкиattr_accessor
вызывается метод, который, в свою очередь, изменяет текущий класс - запомните неявный получатель:,self.attr_accessor
гдеself
находится «открытый» объект класса в этой точке.Потребность
attr_accessor
и в друзьях, ну иRuby, как и Smalltalk, не разрешает доступ к переменным экземпляра вне методов 1 для этого объекта. То есть переменные экземпляра не могут быть доступны в
x.y
форме, как это принято в, скажем, Java или даже Python. В Rubyy
всегда принимается сообщение для отправки (или «метод для вызова»). Таким образом,attr_*
методы создают оболочки, которые обеспечивают@variable
доступ к экземпляру через динамически создаваемые методы.Котел отстой
Надеюсь, что это проясняет некоторые мелочи. Удачного кодирования.
1 Это не совсем верно, и в этом есть некоторые «методы» , но нет синтаксической поддержки доступа к «общедоступным переменным экземпляра».
источник
attr_accessor
является (как указано @pst) просто методом. Что он делает, так это создает больше методов для вас.Итак, этот код здесь:
эквивалентно этому коду:
Вы можете написать этот метод самостоятельно в Ruby:
источник
attr_accessor
и нашел здесь, наконец! Хотя это решило мою проблему, но мне любопытно узнать, где (книга / официальный документ) я могу найти пример реализации, подобный этому?attr_accessor
очень просто:это ярлык для:
это не что иное, как получатель / установщик объекта
источник
По сути, они подделывают общедоступные атрибуты данных, которых нет в Ruby.
источник
Это просто метод, который определяет методы получения и установки для переменных экземпляра. Примером реализации будет:
источник
Простое объяснение без кода
Большинство из приведенных выше ответов используют код. Это объяснение пытается ответить на него, не используя ничего, по аналогии / истории:
Внешние стороны не могут получить доступ к внутренним секретам ЦРУ
Давайте представим себе действительно секретное место: ЦРУ. Никто не знает, что происходит в ЦРУ, кроме людей внутри ЦРУ. Другими словами, внешние люди не могут получить доступ к какой-либо информации в ЦРУ. Но поскольку организация, которая является полностью секретной, бесполезна, определенная информация становится доступной внешнему миру - только то, о чем ЦРУ хочет, чтобы все знали, конечно: например, директор ЦРУ, насколько экологически безвреден этот отдел ко всем другим правительственным ведомствам и т. д. Другая информация: например, кто является его тайными оперативниками в Ираке или Афганистане - такие вещи, вероятно, останутся секретом в течение следующих 150 лет.
Если вы находитесь за пределами ЦРУ, вы можете получить доступ только к той информации, которую он предоставил общественности. Или на языке ЦРУ вы можете получить доступ только к информации, которая «очищена».
Информация, которую ЦРУ хочет сделать доступной для широкой публики за пределами ЦРУ, называется: атрибуты.
Значение атрибутов read и write:
В случае с ЦРУ большинство атрибутов «только для чтения». Это означает , что если вы являетесь участником внешней ЦРУ, вы можете спросить: «кто является директором ЦРУ?» и вы получите прямой ответ. Но что вы не можете сделать с атрибутами «только для чтения», так это вносить изменения в CIA. например, вы не можете позвонить и вдруг решите, что хотите, чтобы Ким Кардашьян был директором, или что вы хотите, чтобы Пэрис Хилтон была главнокомандующим.
Если атрибуты предоставили вам доступ для «записи», тогда вы можете вносить изменения, если хотите, даже если вы были снаружи. В противном случае, единственное, что вы можете сделать, это прочитать.
Другими словами, средства доступа позволяют вам делать запросы или вносить изменения в организации, которые в противном случае не допускают внешних сотрудников, в зависимости от того, являются ли средства доступа доступными для чтения или записи.
Объекты внутри класса могут легко получить доступ друг к другу
Точно то же самое с классами и вашей возможностью доступа к переменным, свойствам и методам внутри них. НТН! Любые вопросы, пожалуйста, задавайте, и я надеюсь, что смогу уточнить.
источник
Если вы знакомы с концепцией ООП, вы должны быть знакомы с методами получения и установки. attr_accessor делает то же самое в Ruby.
Геттер и сеттер в общем пути
Сеттер Метод
Метод получения
Метод получения и установки в Ruby
источник
Я тоже столкнулся с этой проблемой и написал довольно длинный ответ на этот вопрос. На этот счет уже есть несколько отличных ответов, но всем, кто ищет уточнения, я надеюсь, что мой ответ поможет
Метод инициализации
Initialize позволяет вам устанавливать данные для экземпляра объекта при создании экземпляра, а не устанавливать их в отдельной строке кода каждый раз, когда вы создаете новый экземпляр класса.
В приведенном выше коде мы устанавливаем имя «Denis» с помощью метода initialize, передавая Dennis через параметр в Initialize. Если бы мы хотели установить имя без метода инициализации, мы могли бы сделать это так:
В приведенном выше коде мы устанавливаем имя, вызывая метод установщика attr_accessor с использованием person.name, а не устанавливая значения при инициализации объекта.
Оба «метода» выполнения этой работы, но инициализация экономят нам время и строки кода.
Это единственная работа по инициализации. Вы не можете вызвать инициализацию как метод. Чтобы фактически получить значения объекта экземпляра, вам нужно использовать методы получения и установки (attr_reader (get), attr_writer (set) и attr_accessor (оба)). Смотрите ниже для более подробной информации о них.
Получатели, Установщики (attr_reader, attr_writer, attr_accessor)
Getters, attr_reader: Цель геттера - вернуть значение определенной переменной экземпляра. Посетите пример кода ниже для разбивки этого.
В приведенном выше коде вы вызываете методы «item_name» и «amount» в экземпляре Item «example». «Put example.item_name» и «example.quantity» вернут (или «получат») значение для параметров, которые были переданы в «example», и отобразят их на экране.
К счастью, в Ruby есть собственный метод, который позволяет нам писать этот код более кратко; метод attr_reader. Смотрите код ниже;
Этот синтаксис работает точно так же, только он экономит нам шесть строк кода. Представьте, если бы у вас было еще 5 состояний, относящихся к классу Item? Код станет длинным быстро.
Сеттеры, attr_writer: Сначала меня поразили методы сеттера: мне показалось, что он выполняет функцию, идентичную методу инициализации. Ниже я объясняю разницу на основе моего понимания;
Как указывалось выше, метод initialize позволяет вам устанавливать значения для экземпляра объекта при создании объекта.
Но что, если вы хотите установить значения позже, после создания экземпляра или изменить их после их инициализации? Это будет сценарий, в котором вы будете использовать метод установки. ЭТО РАЗНИЦА. Вам не нужно «устанавливать» определенное состояние, когда вы изначально используете метод attr_writer.
Приведенный ниже код является примером использования метода установки для объявления значения item_name для этого экземпляра класса Item. Обратите внимание, что мы продолжаем использовать метод getter attr_reader, чтобы мы могли получать значения и выводить их на экран, на тот случай, если вы захотите протестировать код самостоятельно.
Приведенный ниже код является примером использования attr_writer, чтобы еще раз сократить наш код и сэкономить нам время.
Приведенный ниже код является повторением приведенного выше примера инициализации, где мы используем инициализацию для установки значения объектов item_name при создании.
attr_accessor: выполняет функции как attr_reader, так и attr_writer, сохраняя вам еще одну строку кода.
источник
Я думаю, что часть того, что смущает новых Rubyists / программистов (таких как я):
«Почему я не могу просто сказать экземпляру, что у него есть какой-либо заданный атрибут (например, имя), и присвоить этому атрибуту значение одним махом?»
Немного более обобщенно, но вот как это у меня получилось:
Данный:
Мы не определили Person как нечто, что может иметь имя или любые другие атрибуты в этом отношении.
Итак, если мы тогда:
... и попытаться дать им имя ...
Мы получаем ошибку, потому что в Rubyland класс объекта Person не является чем-то, что связано или способно иметь «имя» ... пока!
НО мы можем использовать любой из данных методов (см. Предыдущие ответы) как способ сказать: «Экземпляр класса Person (
baby
) теперь может иметь атрибут с именем« name », поэтому у нас есть не только синтаксический способ получения и установить это имя, но для нас имеет смысл сделать это ".Опять же, задание этого вопроса с немного другой и более общей точки зрения, но я надеюсь, что это поможет следующему экземпляру класса Person, который найдет свой путь к этой теме.
источник
Проще говоря, это определит сеттер и геттер для класса.
Обратите внимание, что
Так
эквивалентны, чтобы определить сеттер и геттер для класса.
источник
Просто
attr-accessor
создаетgetter
иsetter
методы для указанных атрибутовисточник
Другой способ понять это - выяснить, какой код ошибки он устраняет, имея
attr_accessor
.Пример:
Доступны следующие методы:
Следующие методы выдают ошибку:
owner
иbalance
технически не метод , а атрибут. Класс BankAccount не имеетdef owner
иdef balance
. Если это так, то вы можете использовать две команды ниже. Но этих двух методов нет. Однако вы можете обращаться к атрибутам так, как если бы вы обращались к методу черезattr_accessor
!! Отсюда и словоattr_accessor
. Атрибут. Accessor. Он обращается к атрибутам, как если бы вы обращались к методу.Добавление
attr_accessor :balance, :owner
позволяет читать и писатьbalance
иowner
«метод». Теперь вы можете использовать последние 2 метода.источник
Определяет именованный атрибут для этого модуля, где имя - это symbol.id2name, создавая переменную экземпляра (@name) и соответствующий метод доступа для его чтения. Также создает метод с именем name = для установки атрибута.
источник
Подводя итог, атрибут accessor aka attr_accessor дает вам два бесплатных метода.
Как и в Java, их называют геттерами и сеттерами.
Многие ответы показали хорошие примеры, поэтому я буду кратким.
#the_attribute
а также
# The_attribute =
В старых документах ruby хэш-тег # означает метод. Он также может включать префикс имени класса ... MyClass # my_method
источник
Я новичок в ruby и должен был просто разобраться в следующей странности. Может помочь кому-то еще в будущем. В конце концов, как было упомянуто выше, обе функции (def myvar, def myvar =) обе неявно получают доступ к @myvar, но эти методы могут быть переопределены локальными объявлениями.
источник
Атрибуты и методы доступа
Атрибуты являются компонентами класса, к которым можно получить доступ снаружи объекта. Они известны как свойства во многих других языках программирования. Их значения доступны с помощью «точечной нотации», как в object_name.attribute_name. В отличие от Python и некоторых других языков, Ruby не позволяет обращаться к переменным экземпляра напрямую из-за пределов объекта.
В приведенном выше примере c является экземпляром (объектом) класса Car. Мы безуспешно пытались прочитать значение переменной экземпляра колеса снаружи объекта. Случилось так, что Ruby попытался вызвать метод с именем wheel внутри объекта c, но такой метод не был определен. Короче говоря, object_name.attribute_name пытается вызвать метод с именем attribute_name внутри объекта. Чтобы получить доступ к значению переменной wheel извне, нам нужно реализовать метод экземпляра с таким именем, который будет возвращать значение этой переменной при вызове. Это называется методом доступа. В общем контексте программирования обычным способом доступа к переменной экземпляра вне объекта является реализация методов доступа, также известных как методы получения и установки.
В следующем примере мы добавили методы getter и setter в класс Car, чтобы получить доступ к переменной wheel снаружи объекта. Это не «Рубиновый способ» определения методов получения и установки; он служит только для иллюстрации того, что делают методы getter и setter.
Приведенный выше пример работает, и аналогичный код обычно используется для создания методов получения и установки на других языках. Тем не менее, Ruby предоставляет более простой способ сделать это: три встроенных метода, называемые attr_reader, attr_writer и attr_acessor. Метод attr_reader делает переменную экземпляра доступной для чтения извне, attr_writer делает ее доступной для записи, а attr_acessor делает ее читаемой и доступной для записи.
Приведенный выше пример можно переписать так.
В приведенном выше примере атрибут колеса будет доступен для чтения и записи извне объекта. Если бы вместо attr_accessor мы использовали attr_reader, он был бы доступен только для чтения. Если бы мы использовали attr_writer, он был бы только для записи. Эти три метода сами по себе не являются методами получения и установки, но при вызове они создают методы получения и установки для нас. Это методы, которые динамически (программно) генерируют другие методы; это называется метапрограммирование.
Первый (более длинный) пример, в котором не используются встроенные методы Ruby, следует использовать только тогда, когда в методах get и set требуется дополнительный код. Например, методу установки может потребоваться проверить данные или выполнить некоторые вычисления, прежде чем присваивать значение переменной экземпляра.
Доступ к переменным экземпляра (чтение и запись) возможен извне объекта с помощью встроенных методов instance_variable_get и instance_variable_set. Тем не менее, это редко оправдано и, как правило, является плохой идеей, поскольку обход инкапсуляции имеет тенденцию вызывать всевозможные разрушения.
источник
Хммм. Много хороших ответов. Вот мои несколько центов на это.
attr_accessor
это простой метод, который помогает нам очистить ( СУХОЙ ) повторяющиесяgetter and setter
методы.Так что мы можем больше сосредоточиться на написании бизнес-логики и не беспокоиться о методах установки и получения.
источник
Основная функциональность attr_accessor по сравнению с другими - это возможность доступа к данным из других файлов.
Так что обычно у вас есть attr_reader или attr_writer, но хорошая новость в том, что Ruby позволяет вам объединить эти два вместе с attr_accessor. Я думаю, что это мой метод go, потому что он более округлый или универсальный. Кроме того, имейте в виду, что в Rails это устранено, потому что оно делает это за вас в бэкэнде. Другими словами: вам лучше использовать attr_acessor по сравнению с двумя другими, потому что вам не нужно беспокоиться о том, чтобы быть конкретным, аксессор покрывает все это. Я знаю, что это скорее общее объяснение, но оно помогло мне как новичку.
Надеюсь, это помогло!
источник