Development Tip

루비의 클래스 << 자기 관용구

yourdevel 2020. 9. 28. 10:14
반응형

루비의 클래스 << 자기 관용구


class << selfRuby에서 무엇을 합니까?


첫째, 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(대한 self다른 영향을 미치지하지 만 StateMachineExample에 인스턴스) process_state_2. 따라서 호출자가 process메서드 (redefinable을 호출 함 process_hook) 를 호출 할 때마다 상태에 따라 동작이 변경됩니다.


나는 약 슈퍼 간단한 설명 발견 class << self, Eigenclass및 다른 유형 methods이의 블로그 .

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 stores methods in classes and all methods must be associated with a class. The object on which a singleton method is defined is not a class (it is an instance of a class). If only classes can store methods, how can an object store a singleton method? When a singleton method is created, Ruby automatically creates an anonymous class to store that method. These anonymous classes are called metaclasses, also known as singleton classes or eigenclasses. The singleton method is associated with the metaclass which, in turn, is associated with the object on which the singleton method was defined.

If multiple singleton methods are defined within a single object, they are all stored in the same metaclass.

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'…

In the above example, class << z1 changes the current self to point to the metaclass of the z1 object; then, it defines the say_hello method within the metaclass.

Classes are also objects (instances of the built-in class called Class). Class methods are nothing more than singleton methods associated with a class object.

class Zabuton
  class << self
    def stuff
      puts "Stuffing zabuton…"
    end
  end
end

All objects may have metaclasses. That means classes can also have metaclasses. In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self. Hence, the stuff method is defined within the metaclass of the Zabuton class. The above example is just another way to define a class method. IMHO, it's better to use the def self.my_new_clas_method syntax to define class methods, as it makes the code easier to understand. The above example was included so we understand what's happening when we come across the class << self syntax.

Additional info can be found at this post about Ruby Classes.


What class << thing does:

class Hi
  self #=> Hi
  class << self #same as 'class << Hi'
    self #=> #<Class:Hi>
    self == Hi.singleton_class #=> true
  end
end

[it makes self == thing.singleton_class in the context of its block].


What is 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 object inherits its #methods from its #singleton_class.instance_methods and then from its #class.instance_methods.
Here we gave hi's singleton class instance method :a. It could have been done with class << hi instead.
hi's #singleton_class has all instance methods hi's #class has, and possibly some more (:a here).

[instance methods of thing's #class and #singleton_class can be applied directly to thing. when ruby sees thing.a, it first looks for :a method definition in thing.singleton_class.instance_methods and then in thing.class.instance_methods]


By the way - they call object's singleton class == metaclass == eigenclass.


А singleton method is a method that is defined only for a single object.

Example:

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

Singleton's methods of SomeClass

test


Singleton's methods of test_obj

test_2

test_3


In fact if you write any C extensions for your Ruby projects there is really only one way to define a Module method.

rb_define_singleton_method

I know this self business just opens up all kinds of other questions so you could do better by searching each part.

Objects first.

foo = Object.new

Can I make a method for foo?

Sure

def foo.hello
 'hello'
end

What do I do with it?

foo.hello
 ==>"hello"

Just another object.

foo.methods

You get all the Object methods plus your new one.

def foo.self
 self
end

foo.self

Just the foo Object.

Try to see what happens if you make foo from other Objects like Class and Module. The examples from all the answers are nice to play with but you have to work with different ideas or concepts to really understand what is going on with the way the code is written. So now you have lots of terms to go look at.

Singleton, Class, Module, self, Object, and Eigenclass was brought up but Ruby doesn't name Object Models that way. It's more like Metaclass. Richard or __why shows you the idea here. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html And if the blows you away then try looking up Ruby Object Model in search. Two videos that I know of on YouTube are Dave Thomas and Peter Cooper. They try to explain that concept too. It took Dave a long time to get it so don't worry. I'm still working on it too. Why else would I be here? Thanks for your question. Also take a look at the standard library. It has a Singleton Module just as an FYI.

This is pretty good. https://www.youtube.com/watch?v=i4uiyWA8eFk

참고URL : https://stackoverflow.com/questions/2505067/class-self-idiom-in-ruby

반응형