루비class << self
에서 무엇을 합니까?
루비class << self
에서 무엇을 합니까?
답변:
먼저 class << foo
구문은 foo
싱글 톤 클래스 (고유 클래스)를 엽니 다 . 이를 통해 해당 특정 객체에서 호출 된 메소드의 동작을 특수화 할 수 있습니다.
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
이제 질문에 대답하기 위해 : 싱글 톤 클래스를 class << self
열어 self
현재 self
객체 (클래스 또는 모듈 본문 내부에 클래스 또는 모듈 자체 )에 대한 메소드를 재정의 할 수 있습니다 . 일반적으로 이것은 클래스 / 모듈 ( "정적") 메소드를 정의하는 데 사용됩니다.
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
이것은 속기로도 쓸 수 있습니다.
class String
def self.value_of obj
obj.to_s
end
end
또는 더 짧습니다.
def String.value_of obj
obj.to_s
end
함수 정의 내부에서 함수 self
가 호출되는 객체를 나타냅니다. 이 경우 class << self
해당 객체의 싱글 톤 클래스를 엽니 다. 그 중 하나는 가난한 사람의 상태 머신을 구현하는 것입니다.
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
따라서 위의 예에서의 각 인스턴스는 StateMachineExample
에 process_hook
별칭 이 지정되어 process_state_1
있지만 후자는 어떻게 다른 인스턴스에 영향을 미치지 않는지에 process_hook
대해 재정의 할 수 있습니다 . 따라서 호출자가 메소드를 호출 할 때마다 (재정의 가능을 호출 함 ) 상태에 따라 동작이 변경됩니다.self
StateMachineExample
process_state_2
process
process_hook
class << self
클래스 / 모듈 메소드를 작성하기 위해 의보다 일반적인 사용입니다 . 나는 class << self
훨씬 더 관용적 인 사용법이므로 아마도 그 사용을 확장 할 것입니다 .
a
의 singleton_class
이후 a
의 클래스 (변경 후 '하는 것은 inspect
)의 독특한 변종 String
클래스입니다. 싱글 톤 String
클래스를 변경하는 경우 다른 모든 String
인스턴스에 영향을줍니다 . 무엇 아직도 더 이상한 것은 나중에 다시 경우이다 String
재정의 inspect
한 후 a
여전히 새로운 변경 사항을 선택합니다.
class << self
이상 값보다 평균 아무것도 self
블록의 범위 내에서 싱글 톤 클래스에 동일하게 설정되어 있습니까?
나는 약 슈퍼 간단한 설명을 발견 class << self
, Eigenclass
및 방법의 다른 유형을.
Ruby에는 클래스에 적용 할 수있는 세 가지 유형의 메소드가 있습니다.
인스턴스 메소드와 클래스 메소드는 다른 프로그래밍 언어의 동질성과 거의 유사합니다.
class Foo
def an_instance_method
puts "I am an instance method"
end
def self.a_class_method
puts "I am a class method"
end
end
foo = Foo.new
def foo.a_singleton_method
puts "I am a singletone method"
end
Eigenclass
(싱글 톤 메서드 포함) 에 액세스하는 다른 방법은 다음 구문 ( class <<
)을 사용하는 것입니다.
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
이제이 컨텍스트에서 self
클래스 Foo
자체 인 싱글 톤 메소드를 정의 할 수 있습니다 .
class Foo
class << self
def a_singleton_and_class_method
puts "I am a singleton method for self and a class method for Foo"
end
end
end
foo.singleton_class.instance_methods(false)
확인 하는 데 사용할 수 있습니다 .
일반적으로 인스턴스 메소드는 글로벌 메소드입니다. 즉, 정의 된 클래스의 모든 인스턴스에서 사용할 수 있습니다. 반대로 싱글 톤 방법은 단일 객체에서 구현됩니다.
Ruby는 메소드를 클래스에 저장하며 모든 메소드는 클래스와 연관되어야합니다. 싱글 톤 메소드가 정의 된 객체는 클래스가 아닙니다 (클래스의 인스턴스입니다). 클래스 만 메소드를 저장할 수 있다면 객체는 어떻게 싱글 톤 메소드를 저장할 수 있습니까? 싱글 톤 메소드가 작성되면, Ruby는 해당 메소드를 저장할 익명 클래스를 자동으로 작성합니다. 이러한 익명 클래스를 메타 클래스라고하며 단일 클래스 또는 고유 클래스라고도합니다. 싱글 톤 메소드는 메타 클래스와 연관되어 있으며, 이는 싱글 톤 메소드가 정의 된 오브젝트와 연관됩니다.
단일 객체 내에 여러 싱글 톤 메서드가 정의되어 있으면 모두 동일한 메타 클래스에 저장됩니다.
class Zen
end
z1 = Zen.new
z2 = Zen.new
class << z1
def say_hello
puts "Hello!"
end
end
z1.say_hello # Output: Hello!
z2.say_hello # Output: NoMethodError: undefined method `say_hello'…
위의 예에서 << z1 클래스는 z1 객체의 메타 클래스를 가리 키도록 현재 자체를 변경합니다. 그런 다음 메타 클래스 내에 say_hello 메소드를 정의합니다.
클래스는 객체이기도합니다 (클래스라고하는 내장 클래스의 인스턴스). 클래스 메소드는 클래스 객체와 관련된 싱글 톤 메소드에 지나지 않습니다.
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
모든 객체에는 메타 클래스가있을 수 있습니다. 즉, 클래스에는 메타 클래스도있을 수 있습니다. 위의 예에서 class << self는 self를 수정하여 Zabuton 클래스의 메타 클래스를 가리 킵니다. 명시 적 수신자 (메소드가 정의 될 클래스 / 객체)없이 메소드가 정의되면, 현재 범위, 즉 현재 자체 값 내에 내재적으로 정의됩니다. 따라서 stuff 메소드는 Zabuton 클래스의 메타 클래스 내에 정의됩니다. 위의 예제는 클래스 메소드를 정의하는 또 다른 방법입니다. IMHO, def self.my_new_clas_method 구문을 사용하여 코드를 이해하기 쉽도록 클래스 메소드를 정의하는 것이 좋습니다. 위의 예제는 클래스 << 자체 구문을 접할 때 발생하는 상황을 이해하기 위해 포함되었습니다.
이 게시물 에서 Ruby 클래스에 대한 추가 정보를 찾을 수 있습니다 .
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[ self == thing.singleton_class
블록의 맥락에서 이루어짐] .
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hi
객체는 그것 #methods
으로부터 #singleton_class.instance_methods
그리고 나서 그것 으로부터 상속받습니다 #class.instance_methods
.
여기에서 우리는 준 hi
의 싱글 톤 클래스의 인스턴스 방법 :a
. 대신 << hi 클래스를 사용 하여 수행 할 수 있습니다 .
hi
의 #singleton_class
모든 인스턴스 메소드가 hi
의 ' #class
이 있고, 가능성이 좀 더 ( :a
여기).
일의의 [인스턴스 메소드 #class
와는 #singleton_class
일에 직접 적용 할 수 있습니다. 루비가 thing.a를 볼 때, 먼저 : thing.singleton_class.instance_methods에서 메소드 정의를 찾은 다음 thing.class.instance_methods에서 찾습니다.]
그건 그렇고-그들은 객체의 싱글 톤 클래스 == metaclass == eigenclass라고 부릅니다 .
А 싱글 방법은 하나의 객체에 대해서만 정의하는 방법이다.
예:
class SomeClass
class << self
def test
end
end
end
test_obj = SomeClass.new
def test_obj.test_2
end
class << test_obj
def test_3
end
end
puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods
SomeClass의 싱글 톤 메소드
테스트
test_obj의 싱글 톤 방법
test_2
test_3
실제로 Ruby 프로젝트에 대한 C 확장을 작성하는 경우 실제로 모듈 메소드를 정의하는 한 가지 방법 만 있습니다.
rb_define_singleton_method
이 자체 비즈니스는 모든 종류의 다른 질문을 열어서 각 부분을 검색하여 더 잘 할 수 있다는 것을 알고 있습니다.
먼저 객체.
foo = Object.new
foo에 대한 메소드를 만들 수 있습니까?
확실한
def foo.hello
'hello'
end
그것으로 무엇을해야합니까?
foo.hello
==>"hello"
또 다른 물건.
foo.methods
모든 Object 메소드와 새로운 메소드를 얻습니다.
def foo.self
self
end
foo.self
단지 foo 객체입니다.
클래스 및 모듈과 같은 다른 객체에서 foo를 만들면 어떻게되는지 확인하십시오. 모든 답변의 예는 훌륭하지만 코드 작성 방식에 어떤 일이 일어나고 있는지 실제로 이해하려면 다른 아이디어 나 개념으로 작업해야합니다. 이제 살펴볼 용어가 많이 있습니다.
Singleton, Class, Module, self, Object 및 Eigenclass가 등장했지만 Ruby는 그런 식으로 Object Models의 이름을 지정하지 않습니다. 메타 클래스와 비슷합니다. Richard 또는 __why는 여기서 아이디어를 보여줍니다. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html 그리고 만약 당신이 불면 당신은 검색에서 루비 객체 모델을 찾아보십시오. YouTube에서 내가 아는 두 가지 비디오는 Dave Thomas와 Peter Cooper입니다. 그들은 그 개념도 설명하려고 노력합니다. Dave가 그것을 얻는 데 오랜 시간이 걸렸으므로 걱정하지 마십시오. 나는 아직도 그것을하고 있습니다. 내가 왜 또 왔을 까? 질문 해 주셔서 감사합니다. 또한 표준 라이브러리를 살펴보십시오. FYI와 마찬가지로 싱글 톤 모듈이 있습니다.
이것은 꽤 좋습니다. https://www.youtube.com/watch?v=i4uiyWA8eFk