[ruby] 루비의 클래스 << 자체 관용구

루비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

따라서 위의 예에서의 각 인스턴스는 StateMachineExampleprocess_hook별칭 이 지정되어 process_state_1있지만 후자는 어떻게 다른 인스턴스에 영향을 미치지 않는지에 process_hook대해 재정의 할 수 있습니다 . 따라서 호출자가 메소드를 호출 할 때마다 (재정의 가능을 호출 함 ) 상태에 따라 동작이 변경됩니다.selfStateMachineExampleprocess_state_2processprocess_hook


답변

나는 약 슈퍼 간단한 설명을 발견 class << self, Eigenclass및 방법의 다른 유형을.

Ruby에는 클래스에 적용 할 수있는 세 가지 유형의 메소드가 있습니다.

  1. 인스턴스 메소드
  2. 싱글 톤 방법
  3. 수업 방법

인스턴스 메소드와 클래스 메소드는 다른 프로그래밍 언어의 동질성과 거의 유사합니다.

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


답변

일반적으로 인스턴스 메소드는 글로벌 메소드입니다. 즉, 정의 된 클래스의 모든 인스턴스에서 사용할 수 있습니다. 반대로 싱글 톤 방법은 단일 객체에서 구현됩니다.

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 블록의 맥락에서 이루어짐] .


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


답변