Programing

class << Ruby를 사용한 self vs self.method : 무엇이 더 낫습니까?

lottogame 2020. 12. 7. 07:40
반응형

class << Ruby를 사용한 self vs self.method : 무엇이 더 낫습니까?


루비 스타일 가이드는 잘 사용하고 있음을 알려줍니다 self.method_name대신 class method_name. 하지만 왜?

class TestClass
  # bad
  class << self
    def first_method
      # body omitted
    end

    def second_method_etc
      # body omitted
    end
  end

  # good
  def self.first_method
    # body omitted
  end

  def self.second_method_etc
    # body omitted
  end
end

성능 문제가 있습니까?


class << self모든 클래스 메서드를 동일한 블록에 유지하는 데 능숙합니다. 메서드가 def self.method형식 에 추가되면 나중에 파일에 추가 클래스 메서드가 숨겨져 있지 않을 것이라는 보장 (관습과 희망찬 생각 제외)이 없습니다.

def self.method메서드가 클래스 메서드라는 것을 명시 적으로 설명하는 데 능숙하지만 class << self컨테이너를 직접 찾아야합니다.

이 중 어느 것이 당신에게 더 중요한지는 주관적인 결정이며, 또한 얼마나 많은 다른 사람들이 코드를 작업하고 있는지, 그들의 선호도가 무엇인지에 따라 달라집니다.


일반적으로 class << self메타 프로그래밍에서 클래스를 장시간 self로 설정하는 데 사용됩니다. 10 개의 메서드를 작성하려는 경우 다음과 같이 사용합니다.

METHOD_APPENDICES = [1...10]
class << self
  METHOD_APPENDICES.each do |n|
    define_method("method#{n}") { n }
  end
end

이렇게하면 숫자 만 반환하는 10 개의 메서드 (method1, method2, method3 등)가 생성됩니다. class << self이 경우 메타 프로그래밍 self이 중요 하기 때문에 명확성을 위해 사용 합니다 . self.내부에 쓰레기를 넣으면 실제로 읽기가 어려워 집니다.

클래스 메서드를 정상적으로 정의하는 것이라면 self.class_method_name더 많은 사람들이 이해할 가능성이 높기 때문에 고수 하십시오. 청중이 이해하기를 기대하지 않는 한 메타 구문을 가져올 필요가 없습니다.


위에서 언급했듯이 두 스타일 모두 동일 해 보이지만을 사용 class << self하면 클래스 메서드를 private또는 로 표시 할 수 있습니다 protected. 예를 들면 :

class UsingDefSelf
  def self.a; 'public class method'; end
  private
  def self.b; 'public class method!'; end
end

class UsingSingletonClass
  class << self
    def a; 'public class method'; end
    private
    def b; 'private class method'; end
  end
end

private인스턴스 메서드에만 영향을줍니다. 싱글 톤 클래스를 사용하여 우리는 그 클래스의 인스턴스 메소드를 정의하고 있으며 이는 포함하는 클래스의 클래스 메소드로 변합니다!

다음 private같이 클래스 메서드를 표시 할 수도 있습니다 def self.

class UsingDefSelf
  def self.a; 'private class method'; end
  def self.b; 'private class method!'; end
  private_class_method :a, :b
  # In Ruby 2.1 there is an alternative syntax
  private_class_method def self.c; 'private class method!'; end
end

그러나 우리는 그들을 표시 할 수 protected없습니다 protected_class_method. (그러나 class는 singletonclass의 유일한 인스턴스이기 때문에 private 클래스 메서드와 protected 클래스 메서드는 호출 구문이 다른 점을 제외하면 거의 동일합니다.)

Also it is less easier than using class << self to mark private class methods, since you have to list all method names in private_class_method or prefix private_class_method to every private class method definition.


I assume that they think self.* is better because you can say for sure, it's a class or instance method, without having to scroll up and seaching this class << self string.


Whichever you want. Both are very clear for what you do. But I think of some recommendations for this.

When there're only one class method to define, Use def self.xxx. Because for defining only one method, increasing indent level probably become cluttering.

When there're more than one class method to define, Use class << self. Because writing def self.xxx, def self.yyy and def self.zzz is certainly repetition. Create a section for these methods.

When all methods in a class are class method, you can use module with module_function instead of class. This let you define module functions just use def xxx.


So far the question and answers only discuss these two options:

class MyClass
  def self.method_name
    ..
  end
end

class MyClass
  class << self
    def method_name
      ..
    end
  end
end

But here's another option to consider for class methods / singleton methods / static methods / methods that operate on the class level (or whatever else you want to call them):

class MyClass
  def MyClass.method_name
    ..
  end
end

I prefer this option because it's more obvious what it does. The method definition looks just like how it would be called in your code, and it's clear it operates on the class level.

I also come from a Python background where self is used for instance methods, whereas in Ruby, self is used for class methods. This often confuses me, so to avoid thinking "is a self method in Ruby a class or instance method?" I use def ClassName.methodname.

참고URL : https://stackoverflow.com/questions/10964081/class-self-vs-self-method-with-ruby-whats-better

반응형