Что такое attr_accessor в Ruby? - PullRequest
965 голосов
/ 07 декабря 2010

Мне трудно понять attr_accessor в Ruby. Может кто-нибудь объяснить это мне?

Ответы [ 19 ]

7 голосов
/ 12 августа 2014

Проще говоря, он определит сеттер и геттер для класса.

Обратите внимание, что

attr_reader :v is equivalant to 
def v
  @v
end

attr_writer :v is equivalant to
def v=(value)
  @v=value
end

Итак

attr_accessor :v which means 
attr_reader :v; attr_writer :v 

эквивалентны для определения установщика и получателя для класса.

5 голосов
/ 17 марта 2014

Просто attr-accessor создает методы getter и setter для указанных атрибутов

4 голосов
/ 13 сентября 2016

Другой способ понять это - выяснить, какой код ошибки он устраняет, имея attr_accessor.

Пример:

class BankAccount    
  def initialize( account_owner )
    @owner = account_owner
    @balance = 0
  end

  def deposit( amount )
    @balance = @balance + amount
  end

  def withdraw( amount )
    @balance = @balance - amount
  end
end

Доступны следующие методы:

$ bankie = BankAccout.new("Iggy")
$ bankie 
$ bankie.deposit(100)
$ bankie.withdraw(5)

Следующие методы вызывают ошибку:

$ bankie.owner     #undefined method `owner'... 
$ bankie.balance   #undefined method `balance'...

ownerи balance технически не метод , а атрибут.Класс BankAccount не имеет def owner и def balance.Если это так, то вы можете использовать две команды ниже.Но этих двух методов нет.Однако вы можете получить доступ к атрибутам, как если бы вы получили доступ к методу с помощью attr_accessor !! Отсюда и слово attr_accessor.Атрибут.Accessor.Он обращается к атрибутам так же, как к методу.

Добавление attr_accessor :balance, :owner позволяет читать и писать balance и owner «метод».Теперь вы можете использовать последние 2 метода.

$ bankie.balance
$ bankie.owner
2 голосов
/ 11 августа 2015

Определяет именованный атрибут для этого модуля, где имя есть symbol.id2name, создавая переменную экземпляра (@name) и соответствующий метод доступа для его чтения.Также создает метод с именем name = для установки атрибута.

module Mod
  attr_accessor(:one, :two)
end
Mod.instance_methods.sort   #=> [:one, :one=, :two, :two=]
1 голос
/ 14 ноября 2016

Подводя итог, атрибут accessor aka attr_accessor дает вам два бесплатных метода.

Как и в Java, они называются getter и setters.

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

# the_attribute

и

# the_attribute =

В старых документах ruby ​​хеш-тег # означает метод.Он также может включать префикс имени класса ... MyClass # my_method

0 голосов
/ 23 января 2019

Я новичок в ruby ​​и должен был просто разобраться со следующей странностью.Может помочь кому-то еще в будущем.В конце концов, как было упомянуто выше, обе функции (def myvar, def myvar =) обе неявно получают доступ к @myvar, но эти методы могут быть переопределены локальными объявлениями.

class Foo
  attr_accessor 'myvar'
  def initialize
    @myvar = "A"
    myvar = "B"
    puts @myvar # A
    puts myvar # B - myvar declared above overrides myvar method
  end

  def 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 # C
  end
end
0 голосов
/ 04 августа 2017

Хммм.Много хороших ответов.Вот мои несколько центов на это.

  • attr_accessor - это простой метод, который помогает нам очистить ( DRY-ing ) до повторяющихся getter and setter методов.

  • Чтобы мы могли больше сосредоточиться на написании бизнес-логики и не беспокоиться о методах установки и получения.

0 голосов
/ 05 июля 2016

Атрибуты и методы доступа

Атрибуты - это компоненты класса, к которым можно обращаться извне объекта.Они известны как свойства во многих других языках программирования.Их значения доступны с помощью «точечной нотации», как в object_name.attribute_name.В отличие от Python и некоторых других языков, Ruby не позволяет обращаться к переменным экземпляра напрямую из-за пределов объекта.

class Car
  def initialize
    @wheels = 4  # This is an instance variable
  end
end

c = Car.new
c.wheels     # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>

В приведенном выше примере c является экземпляром (объектом) класса Car.Мы безуспешно пытались прочитать значение переменной экземпляра колеса снаружи объекта.Случилось так, что Ruby попытался вызвать метод с именем wheel внутри объекта c, но такой метод не был определен.Вкратце, имя_объекта.attribute_name пытается вызвать метод с именем имя_атрибута внутри объекта.Чтобы получить доступ к значению переменной wheel извне, нам нужно реализовать метод экземпляра с таким именем, который будет возвращать значение этой переменной при вызове.Это называется методом доступа.В общем контексте программирования обычным способом доступа к переменной экземпляра вне объекта является реализация методов доступа, также известных как методы получения и установки.Метод получения позволяет считывать значение переменной, определенной в классе, извне, а метод установки позволяет записывать ее извне.

В следующем примере мы добавили методы получения и установки кКласс автомобиля для доступа к переменным колесам снаружи объекта.Это не «Рубиновый способ» определения методов получения и установки;он служит только для иллюстрации того, что делают методы получения и установки.

class Car
  def wheels  # getter method
    @wheels
  end

  def wheels=(val)  # setter method
    @wheels = val
  end
end

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 делает ее читаемой и доступной для записи.

Приведенный выше пример можно переписать так:

class Car
  attr_accessor :wheels
end

f = Car.new
f.wheels = 4
f.wheels  # Output: => 4

В приведенном выше примере атрибут wheel будет доступен для чтения и записи извне объекта.Если бы вместо attr_accessor мы использовали attr_reader, он был бы доступен только для чтения.Если бы мы использовали attr_writer, он был бы только для записи.Эти три метода сами по себе не являются методами получения и установки, но при вызове они создают методы получения и установки для нас.Это методы, которые динамически (программно) генерируют другие методы;это называется метапрограммирование.

Первый (более длинный) пример, в котором не используются встроенные методы Ruby, должен использоваться только тогда, когда в методах get и set требуется дополнительный код.Например, для метода установки может потребоваться проверить данные или выполнить некоторые вычисления, прежде чем присваивать значение переменной экземпляра.

Доступ к переменным экземпляра (чтение и запись) возможен извне объекта с помощью встроенных методов instance_variable_get и instance_variable_set.Тем не менее, это редко оправдано и, как правило, является плохой идеей, так как обход инкапсуляции может привести к разного рода разрушениям.

0 голосов
/ 17 июня 2016

Основная функциональность attr_accessor по сравнению с другими - это возможность доступа к данным из других файлов.
Так что обычно у вас есть attr_reader или attr_writer, но хорошая новость в том, что Ruby позволяет вам объединить эти два вместе с attr_accessor. Я думаю о нем как о методе «пойти» , потому что он более округлый или универсальный. Кроме того, имейте в виду, что в Rails это устранено, потому что оно делает это за вас в бэкэнде. Другими словами: вам лучше использовать attr_acessor по сравнению с двумя другими, потому что вам не нужно беспокоиться о том, чтобы быть конкретным, аксессор покрывает все это. Я знаю, что это скорее общее объяснение, но оно помогло мне как новичку.

Надеюсь, это помогло!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...