Ruby에서 attr_accessor는 무엇입니까?
attr_accessor
Ruby를 이해하는 데 어려움을 겪고 있습니다. 누군가 나에게 이것을 설명 할 수 있습니까?
수업이 있다고 가정 해 보겠습니다 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 는 단지 메소드 입니다. (링크는 작동 방식에 대한 더 많은 통찰력을 제공해야합니다. 생성 된 메서드 쌍을 살펴보고 자습서에서 사용 방법을 보여줄 것입니다.)
트릭은 즉 class
입니다 정의하지 (은 C ++ 및 Java와 같은 언어에서 "단지 정의"입니다) 루비, 그러나 그것은이다 평가하는 표현 . attr_accessor
현재 클래스를 수정 하는 메서드가 호출되는 것은 이 평가 동안입니다 . 암시 적 수신자를 기억하십시오 .이 시점에서 "개방형"클래스 객체는 self.attr_accessor
어디에 있습니까 self
?
attr_accessor
그리고 친구에 대한 필요성은 다음 과 같습니다.
Ruby는 Smalltalk와 마찬가지로 해당 객체에 대한 메소드 1 외부에서 인스턴스 변수에 액세스하는 것을 허용하지 않습니다 . 즉, 인스턴스 변수
x.y
는 일반적으로 Java 또는 Python과 같은 형식으로 액세스 할 수 없습니다 . 루비y
에서는 항상 보낼 메시지 (또는 "호출 방법")로 간주됩니다. 따라서attr_*
메서드는@variable
동적으로 생성 된 메서드를 통해 인스턴스 액세스를 프록시하는 래퍼를 생성합니다.Boilerplate 짜증
이것이 약간의 세부 사항을 명확히하기를 바랍니다. 즐거운 코딩입니다.
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
매우 간단합니다.
attr_accessor :foo
다음에 대한 바로 가기입니다.
def foo=(val)
@foo = val
end
def foo
@foo
end
객체에 대한 getter / setter에 불과합니다.
기본적으로 공개적으로 액세스 할 수있는 데이터 속성을 위조하지만 Ruby에는 없습니다.
인스턴스 변수에 대한 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이 감독이되기를 원하거나 패리스 힐튼이 최고 사령관이되기를 원한다고 결정 합니다.
속성이 "쓰기"액세스 권한을 부여한 경우 외부에 있더라도 원하는 경우 변경할 수 있습니다. 그렇지 않으면, 당신이 할 수있는 유일한 일은 읽는 것입니다.
즉, 접근자를 사용하면 접근자가 읽기 또는 쓰기 접근 자인지 여부에 따라 외부 사용자를 허용하지 않는 조직에 대해 문의하거나 변경할 수 있습니다.
클래스 내의 개체는 서로 쉽게 액세스 할 수 있습니다.
- 반면에 이미 CIA 내부에 있었다면 카불에있는 CIA 요원을 쉽게 호출 할 수 있습니다.이 정보는 이미 내부에있는 경우 쉽게 액세스 할 수 있기 때문입니다. 그러나 CIA 외부에 있는 경우 단순히 액세스 권한이 부여되지 않습니다. 사용자가 누구인지 (읽기 액세스) 알 수 없으며 그들의 임무 (쓰기 액세스)를 변경할 수 없습니다.
클래스와 그 안의 변수, 속성 및 메서드에 액세스 할 수있는 능력도 똑같습니다. 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"
나는이 문제에 직면했고이 질문에 대해 다소 긴 답을 썼다. 이미 이에 대한 훌륭한 답변이 있지만 더 자세한 설명을 원하는 사람은 내 답변이 도움이되기를 바랍니다.
초기화 방법
Initialize를 사용하면 클래스의 새 인스턴스를 만들 때마다 코드에서 별도의 줄에 데이터를 설정하지 않고 인스턴스를 만들 때 개체의 인스턴스에 데이터를 설정할 수 있습니다.
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 클래스의 다음 인스턴스에 도움이되기를 바랍니다.
간단히 말해서 클래스에 대한 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를 정의하는 것과 동일합니다.
지정된 속성에 대한 및 메서드를 간단히 attr-accessor
만듭니다.getter
setter
이를 이해하는 또 다른 방법은 .NET을 사용하여 제거하는 오류 코드를 파악하는 것 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
"방법"을 사용할 수 있습니다. 이제 마지막 두 가지 방법을 사용할 수 있습니다.
$ bankie.balance
$ bankie.owner
이 모듈의 명명 된 속성을 정의합니다. 여기서 이름은 symbol.id2name이고 인스턴스 변수 (@name) 및이를 읽을 해당 액세스 방법을 만듭니다. 또한 속성을 설정하기 위해 name =이라는 메서드를 만듭니다.
module Mod
attr_accessor(:one, :two)
end
Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]
속성 접근자를 요약하기 위해 attr_accessor는 두 가지 무료 메서드를 제공합니다.
Java와 마찬가지로 getter 및 setter라고합니다.
많은 답변이 좋은 예를 보여 주었으므로 간략히 설명하겠습니다.
#the_attribute
과
# the_attribute =
이전 루비 문서에서 해시 태그 #은 메소드를 의미합니다. 클래스 이름 접두사를 포함 할 수도 있습니다 ... MyClass # my_method
속성 및 접근 자 메서드
속성은 객체 외부에서 액세스 할 수있는 클래스 구성 요소입니다. 다른 많은 프로그래밍 언어에서는 속성으로 알려져 있습니다. 해당 값은 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 클래스의 인스턴스 (객체)입니다. 객체 외부에서 wheels 인스턴스 변수의 값을 읽는 데 실패했습니다. 무슨 일이 있었는지 Ruby가 c 객체 내에서 wheels라는 메서드를 호출하려고 시도했지만 그러한 메서드가 정의되지 않았습니다. 간단히 말해 object_name.attribute_name은 개체 내에서 attribute_name이라는 메서드를 호출하려고합니다. 외부에서 wheels 변수의 값에 액세스하려면 해당 이름으로 인스턴스 메서드를 구현해야합니다.이 메서드는 호출 될 때 해당 변수의 값을 반환합니다. 이를 접근 자 메서드라고합니다. 일반적인 프로그래밍 컨텍스트에서 개체 외부에서 인스턴스 변수에 액세스하는 일반적인 방법은 getter 및 setter 메서드라고도하는 접근 자 메서드를 구현하는 것입니다.
다음 예제에서는 객체 외부에서 wheels 변수에 액세스하기 위해 Car 클래스에 getter 및 setter 메서드를 추가했습니다. 이것은 게터와 세터를 정의하는 "루비 방식"이 아닙니다. 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 개의 함수 (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
흠. 많은 좋은 답변. 여기에 몇 센트가 있습니다.
attr_accessor
반복되는 방법 을 청소 ( DRY-ing ) 하는 데 도움이되는 간단한 방법입니다 .getter and setter
그래서 우리는 setter와 getter에 대해 걱정하지 않고 비즈니스 로직 작성에 더 집중할 수 있습니다.
attr_accessor 의 주요 기능은 다른 파일에서 데이터에 액세스하는 기능입니다.
따라서 일반적으로 attr_reader 또는 attr_writer가 있지만 좋은 소식은 Ruby가이 두 가지를 attr_accessor와 결합 할 수 있다는 것입니다. 좀 더 둥글거나 다재다능하기 때문에 내 방법 이라고 생각합니다 . 또한 Rails에서는 백엔드에서이 작업을 수행하기 때문에 제거되었습니다. 즉, 다른 두 개에 대해 attr_acessor를 사용하는 것이 더 낫습니다. 왜냐하면 특정에 대해 걱정할 필요가 없기 때문에 접근자가 모든 것을 다룹니다. 나는 이것이 일반적인 설명에 가깝다는 것을 알고 있지만 초보자로서 나를 도왔습니다.
이것이 도움이 되었기를 바랍니다!
참고 URL : https://stackoverflow.com/questions/4370960/what-is-attr-accessor-in-ruby
'Development Tip' 카테고리의 다른 글
jQuery를 사용하여 div의 innerHTML을 대체하는 방법은 무엇입니까? (0) | 2020.09.27 |
---|---|
CSS로 div의 종횡비 유지 (0) | 2020.09.27 |
Node.js / Windows 오류 : ENOENT, stat 'C : \ Users \ RT \ AppData \ Roaming \ npm' (0) | 2020.09.27 |
Git에서 삭제 한 분기를 복구 할 수 있습니까? (0) | 2020.09.27 |
이것은 (0) | 2020.09.27 |