Rubyattr_accessor
에서 이해하는 데 어려움을 겪고 있습니다.
누군가 나에게 이것을 설명 할 수 있습니까?
Rubyattr_accessor
에서 이해하는 데 어려움을 겪고 있습니다.
누군가 나에게 이것을 설명 할 수 있습니까?
답변:
수업이 있다고 가정 해 봅시다 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"
대박. 이제 @name
reader와 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"
같은 방식으로 작동합니다! @name
person 객체 의 인스턴스 변수 는 수동으로 수행했을 때와 같이 설정되므로 다른 방법으로 사용할 수 있습니다.
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
다른 답변, 책, 루비 문서를, 방법은 실제로 당신을위한 방법을 생성 읽습니다.
attr_accessor
현재 클래스에서 호출되는 메서드이며 해당 메서드에 :name
전달하는 매개 변수 라는 것을 이해해야합니다 . 특별한 구문이 아니며 간단한 메소드 호출입니다. @name
변수에 변수 를 주면 @name에 포함되므로 의미가 없습니다 nil
. 그래서 글을 쓰는 것과 같습니다 attr_accessor nil
. 작성해야 할 변수를 전달하지 않고 변수를 호출 할 이름을 전달합니다.
name
와 변수 @name
는 동일하지 않습니다. 혼동하지 마십시오. @name
클래스에 인스턴스 변수 가 attr_reader :name
있으며 외부에서 읽을 수 있도록 정의 합니다. 없이 attr_reader
간단한 방법이 없습니다 당신이 액세스 할 수있는 @name
클래스의 외부.
attr_accessor 는 단지 메소드 입니다. (링크는 작동 방식에 대한 더 많은 통찰력을 제공해야합니다. 생성 된 메소드 쌍을 살펴보고 튜토리얼에서이를 사용하는 방법을 보여 주어야합니다.)
트릭은 Ruby 의 정의class
가 아니며 (C ++ 및 Java와 같은 언어에서는 "그냥 정의"임), 평가 하는 표현식입니다 . 때이 평가 중입니다 attr_accessor
방법은 차례 수정에 현재 클래스가있는 호출 - 암시 수신기를 기억 self.attr_accessor
곳 self
이 시점에서 "열기"클래스 개체입니다.
attr_accessor
친구 의 필요성은 다음 과 같습니다.
스몰 토크처럼 루비 는 해당 객체에 대한 메소드 1 외부에서 인스턴스 변수에 액세스 할 수 없습니다 . 즉, 인스턴스 변수는 x.y
Java 또는 Python과 같이 일반적인 형태로 액세스 할 수 없습니다 . 루비 y
에서는 항상 보낼 메시지 (또는 "메소드 호출 방법")로 사용됩니다. 따라서 attr_*
메소드는 @variable
동적으로 작성된 메소드를 통해 인스턴스 액세스를 프록시하는 랩퍼를 작성합니다.
보일러 플레이트 짜증
이것이 약간의 세부 사항을 명확히하기를 바랍니다. 행복한 코딩.
1 이것은 사실이 아니며 이에 대한 "기술"이 있지만 "공개 인스턴스 변수"액세스에 대한 구문 지원은 없습니다.
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
attr_accessor
마침내 여기에서 발견되었다! 내 문제를 해결했지만 이런 구현 예제를 어디에서 찾을 수 있는지 궁금합니다 (book / official doc)?
attr_accessor
매우 간단합니다 :
attr_accessor :foo
다음에 대한 바로 가기입니다.
def foo=(val)
@foo = val
end
def foo
@foo
end
객체에 대한 getter / setter에 지나지 않습니다.
기본적으로 루비에는없는 공개적으로 액세스 가능한 데이터 속성을 위조합니다.
인스턴스 변수에 대한 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
위의 답변 중 대부분은 코드를 사용합니다. 이 설명은 유추 / 이야기를 통해 아무 것도 사용하지 않고 대답하려고합니다.
외부 당사자는 내부 CIA 비밀에 액세스 할 수 없습니다
CIA라는 정말 비밀스러운 장소를 상상해 봅시다. CIA 내부의 사람들을 제외하고 CIA에서 무슨 일이 일어나고 있는지 아무도 모른다. 즉, 외부인은 CIA의 정보에 액세스 할 수 없습니다. 그러나 완전히 비밀을 유지하는 조직을 보유하는 것은 좋지 않기 때문에 특정 정보를 외부 세계에 공개 할 수 있습니다. CIA가 모든 사람이 당연히 알고 싶어하는 것만 : CIA 국장,이 부서의 환경 친화적 비교 기타 정보 : 기타 정보 : 예 : 이라크 또는 아프가니스탄에서 비밀 요원이되는 사람 – 이러한 유형의 물건은 아마도 향후 150 년 동안 비밀로 남아있을 것입니다.
CIA 외부에있는 경우 공개적으로 제공 한 정보에만 액세스 할 수 있습니다. 또는 CIA 용어를 사용하려면 "삭제 된"정보에만 액세스 할 수 있습니다.
CIA가 CIA 외부의 일반 대중에게 제공하고자하는 정보를 속성 이라고 합니다.
읽기 및 쓰기 속성의 의미 :
CIA의 경우 대부분의 속성은 "읽기 전용"입니다. 이는 귀하가 CIA 외부 당사자 인 경우 "CIA 책임자는 누구입니까?"라고 요청할 수 있습니다 . 그리고 당신은 정답을 얻을 것입니다. 그러나 "읽기 전용"속성으로 수행 할 수없는 것은 CIA를 변경하는 것입니다. 예를 들어, 전화를 걸 수 없으며 Kim Kardashian이 감독이되기를 원하거나 Paris Hilton이 최고 사령관이되기를 원한다고 갑자기 결정 합니다.
속성이 "쓰기"액세스 권한을 부여한 경우 외부에 있더라도 원하는 경우 변경할 수 있습니다. 그렇지 않으면, 당신이 할 수있는 유일한 것은 읽기입니다.
즉, 접근자는 접근자가 읽기 또는 쓰기 접근 자인지에 따라 외부인을 허용하지 않는 조직에 대해 문의하거나 변경을 수행 할 수 있습니다.
클래스 내부의 객체는 서로 쉽게 액세스 할 수 있습니다.
클래스와 그 안의 변수, 속성 및 메서드에 액세스 할 수있는 기능과 똑같은 것입니다. HTH! 질문이 있으시면 언제든지 문의하십시오. 명확히 할 수 있기를 바랍니다.
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"
나는이 문제에 직면 하여이 질문에 대해 다소 긴 답변을 썼습니다. 이것에 대해서는 이미 훌륭한 답변이 있지만 더 많은 설명을 원하는 사람은 내 답변이 도움이되기를 바랍니다.
초기화 방법
초기화를 사용하면 클래스의 새 인스턴스를 만들 때마다 코드에서 별도의 줄에 데이터를 설정하지 않고 인스턴스를 만들 때 데이터를 객체의 인스턴스로 설정할 수 있습니다.
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의 기능을 수행하여 한 줄의 코드를 더 저장합니다.
새로운 루비 스트 / 프로그래머 (혼자처럼)를 혼란스럽게 만드는 부분은 다음과 같습니다.
"인스턴스에 주어진 속성 (예 : 이름)이 있고 그 속성에 값을 한 번에 줄 수있는 이유는 무엇입니까?"
좀 더 일반화되었지만 이것이 나를 위해 클릭 한 방법입니다.
주어진:
class Person
end
우리는 Person 을 그 문제 의 이름 이나 다른 속성을 가질 수있는 것으로 정의하지 않았습니다 .
우리가 그렇다면 :
baby = Person.new
... 그리고 그들에게 이름을 주려고 노력하십시오 ...
baby.name = "Ruth"
우리는 얻을 오류를 Rubyland에, 객체의 Person 클래스는하지와 관련된 또는 "이름"을 가질 수있다 뭔가 때문에 아직 ...!
그러나 "Person 클래스 ( baby
) 의 인스턴스 는 이제 'name'이라는 속성을 가질 수 있으므로 주어진 메소드 중 하나를 사용할 수 있습니다 (이전 답변 참조 ). 그 이름을 정했지만 그렇게하는 것이 합리적입니다. "
다시 말하지만, 약간 다른 일반적인 각도 에서이 질문을 쳤지 만이 스레드로가는 Person 클래스의 다음 인스턴스에 도움이되기를 바랍니다.
이를 이해하는 또 다른 방법은를 사용하여 제거하는 오류 코드를 파악하는 것 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
추가 attr_accessor :balance, :owner
하면 읽고 쓰는 방법 balance
과 owner
"방법"을 사용할 수 있습니다. 이제 마지막 2 가지 방법을 사용할 수 있습니다.
$ bankie.balance
$ bankie.owner
이 모듈의 이름 지정된 속성을 정의합니다. 여기서 이름은 symbol.id2name이며 인스턴스 변수 (@name) 및 해당 액세스 방법을 작성합니다. 또한 name =이라는 메소드를 작성하여 속성을 설정하십시오.
module Mod
attr_accessor(:one, :two)
end
Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]
나는 루비를 처음 접했고 다음과 같은 이상한 점을 이해해야했습니다. 앞으로 다른 사람을 도울 수 있습니다. 결국 위에서 언급 한 것처럼 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
속성은 객체 외부에서 액세스 할 수있는 클래스 구성 요소입니다. 그것들은 다른 많은 프로그래밍 언어에서 속성으로 알려져 있습니다. 해당 값은 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 내장 메소드를 사용하여 오브젝트 외부에서 인스턴스 변수에 액세스 (읽기 및 쓰기) 할 수 있습니다. 그러나 캡슐화를 우회하는 것이 모든 종류의 혼란을 초래하는 경향이 있기 때문에 이것은 거의 정당화되지 않으며 일반적으로 나쁜 생각입니다.
흠. 좋은 답변이 많이 있습니다. 여기에 몇 센트가 있습니다.
attr_accessor
반복 방법 을 정리 ( DRY-ing ) 하는 데 도움이되는 간단한 방법입니다 .getter and setter
따라서 비즈니스 로직 작성에 더 집중하고 세터와 게터에 대해 걱정할 필요가 없습니다.
다른 것보다 attr_accessor 의 주요 기능은 다른 파일에서 데이터에 액세스하는 기능입니다.
일반적으로 attr_reader 또는 attr_writer를 사용하지만 루비를 사용하면이 두 가지를 attr_accessor와 결합 할 수 있습니다. 나는 그것이 더 둥글거나 다재 다능하기 때문에 이동 방법 으로 생각합니다 . 또한 Rails에서는 백엔드에서이를 수행하므로 제거되지 않습니다. 다른 말로하면 : 당신은 특정 두 가지에 대해 걱정할 필요가 없기 때문에 다른 두 가지보다 attr_acessor를 사용하는 것이 좋습니다. 액세서가 모든 것을 다룹니다. 나는 이것이 일반적인 설명이라는 것을 알고 있지만 초보자로서 도움이되었습니다.
이것이 도움이 되었기를 바랍니다!