Ruby에서 attr_accessor 란 무엇입니까?


1023

Rubyattr_accessor 에서 이해하는 데 어려움을 겪고 있습니다. 누군가 나에게 이것을 설명 할 수 있습니까?



1
attr_accessor가 Git에서 동일한 방식으로 작동합니까? 일부 자습서는 충분히 설명하지 못하고 다른 자습서는 사전 지식을 가정합니다.
Angelfirenze 2014

10
@Angelfirenze와는 git아무런 관련이 없습니다 attr_accessor. Git은 버전 제어 소프트웨어 인 반면 Rubyattr_accessor메소드입니다 .
우즈 베키 온

답변:


2359

수업이 있다고 가정 해 봅시다 Person.

class Person
end

person = Person.new
person.name # => no method error

분명히 우리는 method를 정의하지 않았다 name. 그걸하자.

class Person
  def name
    @name # simply returning an instance variable @name
  end
end

person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error

아하, 우리는 이름을 읽을 수 있지만 그렇다고해서 이름을 지정할 수있는 것은 아닙니다. 그것들은 두 가지 다른 방법입니다. 전자는 리더 라고 하고 후자는 라이터 라고 합니다. 우리는 아직 작가를 만들지 않았으므로 그렇게하겠습니다.

class Person
  def name
    @name
  end

  def name=(str)
    @name = str
  end
end

person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"

대박. 이제 @namereader와 writer 메소드를 사용하여 인스턴스 변수 를 쓰고 읽을 수 있습니다 . 예외적으로, 이렇게 자주 수행되는데 왜 매번 이러한 방법을 쓰는 데 시간이 낭비됩니까? 우리는 더 쉽게 할 수 있습니다.

class Person
  attr_reader :name
  attr_writer :name
end

이것조차도 반복 될 수 있습니다. 독자와 작가 모두를 원할 때 접근자를 사용하십시오!

class Person
  attr_accessor :name
end

person = Person.new
person.name = "Dennis"
person.name # => "Dennis"

같은 방식으로 작동합니다! @nameperson 객체 의 인스턴스 변수 는 수동으로 수행했을 때와 같이 설정되므로 다른 방법으로 사용할 수 있습니다.

class Person
  attr_accessor :name

  def greeting
    "Hello #{@name}"
  end
end

person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"

그게 다야. 방법을 이해하기 위해 attr_reader, attr_writer그리고 attr_accessor다른 답변, 책, 루비 문서를, 방법은 실제로 당신을위한 방법을 생성 읽습니다.


46
@ hakunin-그 명확한 답변에 감사드립니다. 루비 구문이 attr_ * 문의 인스턴스 변수에 콜론 ':'을 제안하는 이유는 무엇입니까? 변수를 참조하기 위해 클래스의 다른 곳에서 사용되는 동일한 '@'구문을 사용하는 것이 더 직관적 인 것 같습니다.

207
@WilliamSmith 질문에 대답하려면 attr_accessor현재 클래스에서 호출되는 메서드이며 해당 메서드에 :name전달하는 매개 변수 라는 것을 이해해야합니다 . 특별한 구문이 아니며 간단한 메소드 호출입니다. @name변수에 변수 를 주면 @name에 포함되므로 의미가 없습니다 nil. 그래서 글을 쓰는 것과 같습니다 attr_accessor nil. 작성해야 할 변수를 전달하지 않고 변수를 호출 할 이름을 전달합니다.
Max Chernyak

23
@ hakunin-그것은 말이됩니다. 방금 루비가 파일을 통해 구문 분석 할 때 실제로 '실행 중'이고 모든 명령문과 표현식이 실제로 일부 객체의 메소드 호출이라는 것을 알게되었습니다. attr_accessor를 포함합니다. 매우 도움이됩니다.

52
Rails를 3 년 동안 사용했지만이 사실조차 알지 못했습니다. 부끄러움
Sean Xiao

5
@Buminda 예, 그러나 메소드 name와 변수 @name는 동일하지 않습니다. 혼동하지 마십시오. @name클래스에 인스턴스 변수 가 attr_reader :name있으며 외부에서 읽을 수 있도록 정의 합니다. 없이 attr_reader간단한 방법이 없습니다 당신이 액세스 할 수있는 @name클래스의 외부.
Max Chernyak

127

attr_accessor단지 메소드 입니다. (링크는 작동 방식에 대한 더 많은 통찰력을 제공해야합니다. 생성 된 메소드 쌍을 살펴보고 튜토리얼에서이를 사용하는 방법을 보여 주어야합니다.)

트릭은 Ruby 의 정의class아니며 (C ++ 및 Java와 같은 언어에서는 "그냥 정의"임), 평가 하는 표현식입니다 . 때이 평가 중입니다 attr_accessor방법은 차례 수정에 현재 클래스가있는 호출 - 암시 수신기를 기억 self.attr_accessorself이 시점에서 "열기"클래스 개체입니다.

attr_accessor친구 의 필요성은 다음 과 같습니다.

  1. 스몰 토크처럼 루비 는 해당 객체에 대한 메소드 1 외부에서 인스턴스 변수에 액세스 할 수 없습니다 . 즉, 인스턴스 변수는 x.yJava 또는 Python과 같이 일반적인 형태로 액세스 할 수 없습니다 . 루비 y에서는 항상 보낼 메시지 (또는 "메소드 호출 방법")로 사용됩니다. 따라서 attr_*메소드는 @variable동적으로 작성된 메소드를 통해 인스턴스 액세스를 프록시하는 랩퍼를 작성합니다.

  2. 보일러 플레이트 짜증

이것이 약간의 세부 사항을 명확히하기를 바랍니다. 행복한 코딩.


1 이것은 사실이 아니며 이에 대한 "기술"이 있지만 "공개 인스턴스 변수"액세스에 대한 구문 지원은 없습니다.


attr_accessor가 "단지 방법"이라고 말하면 얻을 수 있습니다. 그러나 해당 메소드 를 호출 하는 데 사용되는 구문은 무엇 입니까? 루비 문서에서 some_method : name => "whatever", : notherName, : etc와 같은 구문에 대해 설명하는 섹션을 찾는 데 문제가 있습니다.
BT

68

attr_accessor@pst가 말한 것처럼 그냥 메소드입니다. 그것이하는 일은 더 많은 방법을 만드는 것입니다.

따라서이 코드는 다음과 같습니다.

class Foo
  attr_accessor :bar
end

이 코드와 동일합니다 :

class Foo
  def bar
    @bar
  end
  def bar=( new_value )
    @bar = new_value
  end
end

Ruby에서 이런 종류의 메소드를 직접 작성할 수 있습니다.

class Module
  def 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
    end
  end
end

class Foo
  var :bar
end

f = Foo.new
p f.bar     #=> nil
f.bar = 42
p f.bar     #=> 42

3
메타 프로그래밍이 가장 초보자 수준의 시나리오에서도 사용되는 좋은 예입니다. 아주 좋아요
John Simon

2
나는 구현 스케치를 찾고 있었고 attr_accessor마침내 여기에서 발견되었다! 내 문제를 해결했지만 이런 구현 예제를 어디에서 찾을 수 있는지 궁금합니다 (book / official doc)?
Wasif Hossain

40

attr_accessor 매우 간단합니다 :

attr_accessor :foo

다음에 대한 바로 가기입니다.

def foo=(val)
  @foo = val
end

def foo
  @foo
end

객체에 대한 getter / setter에 지나지 않습니다.


10
당신의 대답은 괜찮습니다. '바로 가기'는 사전에 따라 "구문 설탕"또는 "통역사가 해석하는 매크로"가 아닌 "짧은 대체 경로"를 의미합니다.
bowsersenior

25

기본적으로 루비에는없는 공개적으로 액세스 가능한 데이터 속성을 위조합니다.


4
이 의견이 완전히 유용한 것은 아니지만 사실입니다. 공개 데이터 속성이 Ruby의 "get"메소드 외부에 존재하지 않는다는 사실을 강조합니다. 이는 언어를 배우려는 사람에게 유용한 정보입니다.
Eric Dand

3
이것은 실제로 downvoted해서는 안됩니다. Ruby가 아닌 사람 이이 물건을 이해하려고 시도하면이 답변이 매우 도움이됩니다!
Brad

1
동의합니다. C #의 이름과 매우 유사합니다. {get; set;}
David Miler

17

인스턴스 변수에 대한 getter 및 setter 메소드를 정의하는 메소드 일뿐입니다. 구현 예는 다음과 같습니다.

def self.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 setter
  end
end

이 방법으로 여러 속성을 처리하는 것이 좋습니다!
Wasif Hossain

이것은 메타 프로그래밍과 관련된 또 다른 질문을 해결하는 데 실제로 유용한 코드 스 니펫이었습니다.
alexventuraio

15

코드없이 간단한 설명

위의 답변 중 대부분은 코드를 사용합니다. 이 설명은 유추 / 이야기를 통해 아무 것도 사용하지 않고 대답하려고합니다.

외부 당사자는 내부 CIA 비밀에 액세스 할 수 없습니다

  • CIA라는 정말 비밀스러운 장소를 상상해 봅시다. CIA 내부의 사람들을 제외하고 CIA에서 무슨 일이 일어나고 있는지 아무도 모른다. 즉, 외부인은 CIA의 정보에 액세스 할 수 없습니다. 그러나 완전히 비밀을 유지하는 조직을 보유하는 것은 좋지 않기 때문에 특정 정보를 외부 세계에 공개 할 수 있습니다. CIA가 모든 사람이 당연히 알고 싶어하는 것만 : CIA 국장,이 부서의 환경 친화적 비교 기타 정보 : 기타 정보 : 예 : 이라크 또는 아프가니스탄에서 비밀 요원이되는 사람 – 이러한 유형의 물건은 아마도 향후 150 년 동안 비밀로 남아있을 것입니다.

  • CIA 외부에있는 경우 공개적으로 제공 한 정보에만 액세스 할 수 있습니다. 또는 CIA 용어를 사용하려면 "삭제 된"정보에만 액세스 할 수 있습니다.

  • CIA가 CIA 외부의 일반 대중에게 제공하고자하는 정보를 속성 이라고 합니다.

읽기 및 쓰기 속성의 의미 :

  • CIA의 경우 대부분의 속성은 "읽기 전용"입니다. 이는 귀하가 CIA 외부 당사자 인 경우 "CIA 책임자는 누구입니까?"라고 요청할 수 있습니다 . 그리고 당신은 정답을 얻을 것입니다. 그러나 "읽기 전용"속성으로 수행 할 수없는 것은 CIA를 변경하는 것입니다. 예를 들어, 전화를 걸 수 없으며 Kim Kardashian이 감독이되기를 원하거나 Paris Hilton이 최고 사령관이되기를 원한다고 갑자기 결정 합니다.

  • 속성이 "쓰기"액세스 권한을 부여한 경우 외부에 있더라도 원하는 경우 변경할 수 있습니다. 그렇지 않으면, 당신이 할 수있는 유일한 것은 읽기입니다.

    즉, 접근자는 접근자가 읽기 또는 쓰기 접근 자인지에 따라 외부인을 허용하지 않는 조직에 대해 문의하거나 변경을 수행 할 수 있습니다.

클래스 내부의 객체는 서로 쉽게 액세스 할 수 있습니다.

  • 반면에 이미 CIA 내부에 있다면 Kabul에서 CIA 요원을 쉽게 호출 할 수 있습니다.이 정보는 이미 내부에 있으면 쉽게 액세스 할 수 있기 때문입니다. 그러나 CIA 외부에 있는 경우 액세스 권한이 부여되지 않습니다. 자신이 누구인지 알 수 없으며 (읽기 권한) 미션을 변경할 수 없습니다 (쓰기 권한).

클래스와 그 안의 변수, 속성 및 메서드에 액세스 할 수있는 기능과 똑같은 것입니다. HTH! 질문이 있으시면 언제든지 문의하십시오. 명확히 할 수 있기를 바랍니다.


당신의 설명은 의미가 있습니다! +1 죄송합니다, "CIA에 의해
명확해진

CIA에는 다양한 "클리어런스 (clearance)"레벨이 있습니다. 예 : 극비 (프레 즈 외에는 없음) 또는 대중의 신뢰 (모든 사람이 정보를 읽을 수 있음). CIA는 실제로 매우 멋진 사실을 많이 제공합니다!
BKSpurgeon

당신은 Kardashian을위한 공감대를받을 자격이 있습니다.
rmcsharry

예! 이것이 바로 코드가없는 StackOverflow입니다! :-)
Marvin

13

OOP 개념에 익숙하면 getter 및 setter 메소드에 익숙해야합니다. attr_accessor는 Ruby에서도 동일합니다.

일반적인 방식으로 게터와 세터

class Person
  def name
    @name
  end

  def name=(str)
    @name = str
  end
end

person = Person.new
person.name = 'Eshaan'
person.name # => "Eshaan"

세터 방법

def name=(val)
  @name = val
end

게터 방법

def name
  @name
end

Ruby의 Getter 및 Setter 메소드

class Person
  attr_accessor :name
end

person = Person.new
person.name = "Eshaan"
person.name # => "Eshaan"

2
완벽한 설명! 매우 편리한 동작이며 너무 쉽게 무시할 수 있습니다.
Rubyrider

12

나는이 문제에 직면 하여이 질문에 대해 다소 긴 답변을 썼습니다. 이것에 대해서는 이미 훌륭한 답변이 있지만 더 많은 설명을 원하는 사람은 내 답변이 도움이되기를 바랍니다.

초기화 방법

초기화를 사용하면 클래스의 새 인스턴스를 만들 때마다 코드에서 별도의 줄에 데이터를 설정하지 않고 인스턴스를 만들 때 데이터를 객체의 인스턴스로 설정할 수 있습니다.

class Person

  def initialize(name)
    @name = name
  end


  def greeting
    "Hello #{@name}"
  end
end

person = Person.new("Denis")
puts person.greeting

위의 코드에서 Initialize의 매개 변수를 통해 Dennis를 전달하여 initialize 메서드를 사용하여 "Denis"라는 이름을 설정합니다. initialize 메소드없이 이름을 설정하려면 다음과 같이하면됩니다.

class Person
  attr_accessor :name

  # def initialize(name)
  #     @name = name
  # end

  def greeting
    "Hello #{name}"
  end
end

person = Person.new
person.name = "Dennis"
puts person.greeting

위의 코드에서 객체 초기화시 값을 설정하는 대신 person.name을 사용하여 attr_accessor setter 메소드를 호출하여 이름을 설정했습니다.

이 작업을 수행하는 두 가지“방법”이지만 초기화는 시간과 코드를 절약 해줍니다.

이것이 유일한 초기화 작업입니다. 메소드로 초기화를 호출 할 수 없습니다. 실제로 인스턴스 객체의 값을 얻으려면 getter 및 setter (attr_reader (get), attr_writer (set) 및 attr_accessor (both))를 사용해야합니다. 이에 대한 자세한 내용은 아래를 참조하십시오.

게터, 세터 (attr_reader, attr_writer, attr_accessor)

Getter, attr_reader : Getter의 전체 목적은 특정 인스턴스 변수의 값을 반환하는 것입니다. 이에 대한 자세한 내용은 아래 샘플 코드를 참조하십시오.

class Item

  def initialize(item_name, quantity)
    @item_name = item_name
    @quantity = quantity
  end

  def item_name
    @item_name
  end

  def quantity
     @quantity
  end
end

example = Item.new("TV",2)
puts example.item_name
puts example.quantity

위의 코드에서는“example”항목의 인스턴스에서“item_name”및“quantity”메소드를 호출합니다. "puts example.item_name"및 "example.quantity"는 "example"에 전달 된 매개 변수의 값을 리턴 (또는 "get")하여 화면에 표시합니다.

운좋게도 Ruby에는이 코드를보다 간결하게 작성할 수있는 고유 한 방법이 있습니다. attr_reader 메소드 아래 코드를 참조하십시오.

class Item

attr_reader :item_name, :quantity

  def initialize(item_name, quantity)
    @item_name = item_name
    @quantity = quantity
  end

end

item = Item.new("TV",2)
puts item.item_name
puts item.quantity

이 구문은 정확히 같은 방식으로 작동하며 6 줄의 코드 만 저장합니다. Item 클래스에 5 개의 상태가 더 있다고 상상해보십시오. 코드가 빨리 길어질 것입니다.

Setters, attr_writer : 처음으로 setter 메소드를 사용하게 된 것은 내 눈에 initialize 메소드와 동일한 기능을 수행하는 것 같습니다. 아래에서 나는 나의 이해에 근거한 차이점을 설명합니다.

앞에서 언급했듯이 initialize 메소드를 사용하면 객체 생성시 객체 인스턴스의 값을 설정할 수 있습니다.

그러나 인스턴스가 생성 된 후 나중에 값을 설정하거나 초기화 된 후에 값을 변경하려면 어떻게해야합니까? 이것은 setter 메소드를 사용하는 시나리오입니다. 그것이 차이점입니다. attr_writer 메소드를 처음 사용할 때 특정 상태를 "설정"할 필요는 없습니다.

아래 코드는 setter 메소드를 사용하여 Item 클래스의이 인스턴스에 대한 item_name 값을 선언하는 예입니다. 코드를 직접 테스트하려는 경우를 대비하여 getter 메소드 attr_reader를 계속 사용하여 값을 가져 와서 화면에 인쇄 할 수 있습니다.

class Item

attr_reader :item_name

  def item_name=(str)
    @item_name = (str)
  end

end

아래 코드는 attr_writer를 사용하여 코드를 다시 단축하고 시간을 절약하는 예입니다.

class Item

attr_reader :item_name
attr_writer :item_name

end

item = Item.new
puts item.item_name = "TV"

아래 코드는 위의 초기화 예제를 반복하여 생성시 item_name의 객체 값을 설정하기 위해 initialize를 사용하는 것입니다.

class Item

attr_reader :item_name

  def initialize(item_name)
    @item_name = item_name
  end

end

item = Item.new("TV")
puts item.item_name

attr_accessor : attr_reader 및 attr_writer의 기능을 수행하여 한 줄의 코드를 더 저장합니다.


10

새로운 루비 스트 / 프로그래머 (혼자처럼)를 혼란스럽게 만드는 부분은 다음과 같습니다.

"인스턴스에 주어진 속성 (예 : 이름)이 있고 그 속성에 값을 한 번에 줄 수있는 이유는 무엇입니까?"

좀 더 일반화되었지만 이것이 나를 위해 클릭 한 방법입니다.

주어진:

class Person
end

우리는 Person 을 그 문제 의 이름 이나 다른 속성을 가질 수있는 것으로 정의하지 않았습니다 .

우리가 그렇다면 :

baby = Person.new

... 그리고 그들에게 이름을 주려고 노력하십시오 ...

baby.name = "Ruth"

우리는 얻을 오류를 Rubyland에, 객체의 Person 클래스는하지와 관련된 또는 "이름"을 가질 수있다 뭔가 때문에 아직 ...!

그러나 "Person 클래스 ( baby) 의 인스턴스 는 이제 'name'이라는 속성을 가질 있으므로 주어진 메소드 중 하나를 사용할 수 있습니다 (이전 답변 참조 ). 그 이름을 정했지만 그렇게하는 것이 합리적입니다. "

다시 말하지만, 약간 다른 일반적인 각도 에서이 질문을 쳤지 만이 스레드로가는 Person 클래스의 다음 인스턴스에 도움이되기를 바랍니다.


7

간단히 말해 클래스의 setter와 getter를 정의합니다.

참고

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 

클래스의 setter 및 getter를 정의하는 것과 같습니다.


5

지정된 속성에 대한 및 메소드를 attr-accessor작성하기 만하면 됩니다.gettersetter


5

이를 이해하는 또 다른 방법은를 사용하여 제거하는 오류 코드를 파악하는 것 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'...

ownerbalance하지, 기술적이다 방법 ,하지만 속성. BankAccount 클래스에는 def owner및 이 없습니다 def balance. 그렇다면 다음 두 명령을 사용할 수 있습니다. 그러나이 두 가지 방법은 없습니다. 그러나 !! 를 통해 메소드에 액세스 하는 것처럼 속성에 액세스 할 수 있습니다 ! 따라서 단어 . 속성. 접근 자. 메소드에 액세스하는 것처럼 속성에 액세스합니다.attr_accessorattr_accessor

추가 attr_accessor :balance, :owner하면 읽고 쓰는 방법 balanceowner"방법"을 사용할 수 있습니다. 이제 마지막 2 가지 방법을 사용할 수 있습니다.

$ bankie.balance
$ bankie.owner

2

이 모듈의 이름 지정된 속성을 정의합니다. 여기서 이름은 symbol.id2name이며 인스턴스 변수 (@name) 및 해당 액세스 방법을 작성합니다. 또한 name =이라는 메소드를 작성하여 속성을 설정하십시오.

module Mod
  attr_accessor(:one, :two)
end
Mod.instance_methods.sort   #=> [:one, :one=, :two, :two=]

1

속성 접근자를 요약하면 attr_accessor는 두 가지 무료 방법을 제공합니다.

Java와 마찬가지로 getter 및 setter라고합니다.

많은 답변이 좋은 예를 보여 주었으므로 간단히 설명하겠습니다.

#the_attribute

# the_attribute =

오래된 루비 문서에서 해시 태그 #는 방법을 의미합니다. 또한 클래스 이름 접두사를 포함 할 수 있습니다 ... MyClass # my_method


1

나는 루비를 처음 접했고 다음과 같은 이상한 점을 이해해야했습니다. 앞으로 다른 사람을 도울 수 있습니다. 결국 위에서 언급 한 것처럼 2 개의 함수 (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

속성과 접근 자 메소드

속성은 객체 외부에서 액세스 할 수있는 클래스 구성 요소입니다. 그것들은 다른 많은 프로그래밍 언어에서 속성으로 알려져 있습니다. 해당 값은 object_name.attribute_name에서와 같이 "점 표기법"을 사용하여 액세스 할 수 있습니다. 파이썬과 다른 언어 들과는 달리, 루비는 객체 외부에서 직접 인스턴스 변수에 접근 할 수 없습니다.

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 클래스의 인스턴스 (객체)입니다. 객체 외부에서 wheels 인스턴스 변수의 값을 읽지 못했습니다. 루비는 c 객체 내에서 wheels라는 메소드를 호출하려고 시도했지만 그러한 메소드는 정의되지 않았습니다. 즉, object_name.attribute_name은 오브젝트 내에서 attribute_name이라는 메소드를 호출하려고 시도합니다. 외부에서 wheels 변수의 값에 액세스하려면 해당 이름으로 인스턴스 메소드를 구현해야합니다.이 메소드는 호출 될 때 해당 변수의 값을 리턴합니다. 이것을 접근 자 메서드라고합니다. 일반적인 프로그래밍 컨텍스트에서 객체 외부에서 인스턴스 변수에 액세스하는 일반적인 방법은 getter 및 setter 메서드라고도하는 접근 자 메서드를 구현하는 것입니다.

다음 예제에서는 객체 외부에서 wheels 변수에 액세스하기 위해 getter 및 setter 메소드를 Car 클래스에 추가했습니다. 이것은 게터와 세터를 정의하는 "루비 방식"이 아닙니다. getter 및 setter 메소드가 수행하는 작업을 보여줄뿐입니다.

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

위의 예제가 작동하고 유사한 코드가 일반적으로 다른 언어로 getter 및 setter 메소드를 작성하는 데 사용됩니다. 그러나 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

위의 예에서 wheels 속성은 객체 외부에서 읽고 쓸 수 있습니다. attr_accessor 대신 attr_reader를 사용하면 읽기 전용입니다. attr_writer를 사용하면 쓰기 전용입니다. 이 세 가지 메소드는 자체적으로 getter 및 setter가 아니지만 호출되면 getter 및 setter 메소드를 작성합니다. 그것들은 동적으로 (프로그래밍 방식으로) 다른 방법을 생성하는 방법입니다. 이를 메타 프로그래밍이라고합니다.

Ruby의 내장 메소드를 사용하지 않는 첫 번째 (더 긴) 예제는 getter 및 setter 메소드에 추가 코드가 필요한 경우에만 사용해야합니다. 예를 들어, setter 메소드는 값을 인스턴스 변수에 지정하기 전에 데이터를 유효성 검증하거나 계산을 수행해야 할 수도 있습니다.

instance_variable_get 및 instance_variable_set 내장 메소드를 사용하여 오브젝트 외부에서 인스턴스 변수에 액세스 (읽기 및 쓰기) 할 수 있습니다. 그러나 캡슐화를 우회하는 것이 모든 종류의 혼란을 초래하는 경향이 있기 때문에 이것은 거의 정당화되지 않으며 일반적으로 나쁜 생각입니다.


-2

흠. 좋은 답변이 많이 있습니다. 여기에 몇 센트가 있습니다.

  • attr_accessor반복 방법 을 정리 ( DRY-ing ) 하는 데 도움이되는 간단한 방법입니다 .getter and setter

  • 따라서 비즈니스 로직 작성에 더 집중하고 세터와 게터에 대해 걱정할 필요가 없습니다.


-3

다른 것보다 attr_accessor 의 주요 기능은 다른 파일에서 데이터에 액세스하는 기능입니다.
일반적으로 attr_reader 또는 attr_writer를 사용하지만 루비를 사용하면이 두 가지를 attr_accessor와 결합 할 수 있습니다. 나는 그것이 더 둥글거나 다재 다능하기 때문에 이동 방법 으로 생각합니다 . 또한 Rails에서는 백엔드에서이를 수행하므로 제거되지 않습니다. 다른 말로하면 : 당신은 특정 두 가지에 대해 걱정할 필요가 없기 때문에 다른 두 가지보다 attr_acessor를 사용하는 것이 좋습니다. 액세서가 모든 것을 다룹니다. 나는 이것이 일반적인 설명이라는 것을 알고 있지만 초보자로서 도움이되었습니다.

이것이 도움이 되었기를 바랍니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.