루비는 방법이 없어요.
잠깐만.뭐?
나는 너의 상황을 모르지만, 이것은 내가
Nadia Odunayo
중 처음으로 RubyConf KL 2018
강연을 들었을 때의 확실한 반응이다. (주의해라. 이것은 내가 들은 가장 매력적인 강연 중의 하나이다!)이 글에서 그녀는 루비가 부류의 방법이 없다는 것을 보여 주었다.내가 처음으로 루비를 배우기 시작했을 때, 나는 루비에게 기본적으로 두 가지 방법이 있다는 것을 알게 되었다.
class Foo
def self.class_method
puts "This is a class method of #{self}"
end
def an_instance_method
puts "This is an instance method of #{self}"
end
end
Foo.class_method #=> "This is a class method of Foo"
Foo.new.class_method #=> undefined method `class_method' for #<Foo:0x007f83960d2228> (NoMethodError)
Foo.an_instance_method #=> undefined method `an_instance_method' for Foo:Class (NoMethodError)
Foo.new.an_instance_method #=> This is an instance method of #<Foo:0x007f80aa92d150>
우선, 일리가 있어-A class is an object, and when you call
.new
on a class, you create a new instance of that object.Hence, instance methods are only available on instances of that class.
그래, 그럼.내가 루비에게 방법이 없다고 말했을 때, 나는 무슨 말을 하고 있었습니까?
부모님조부모조상님...!
우리가 먼저 알아야 할 것은 루비의 조상 사슬이다.
조상 사슬은 루비의 작업 원리를 이해하는 데 매우 중요하다.체인의 존재로 인해 전체 방법은 체인을 호출하여 일을 할 수 있지만, 여기서 나는 지나치게 간소화된 해석을 시도할 것이다.
Ruby에서는 모든 것을 계승
Object
하고 각각Object
은 하나BasicObject
에서 계승합니다.빨리 검사해 봅시다!
2.3.1 :001 > Foo.ancestors
=> [Foo, Object, Kernel, BasicObject]
2.3.1 :002 > Foo.superclass #superclass allow us to see what class the receiver inherited from. AKA, the parent of current class.
=> Object
2.3.1 :003 > Object.superclass
=> BasicObject
(Kernel is a Module, you could quickly verify it by doing Kernel.class)
당신이 방법을 호출할 때, 현재 클래스의 방법을 호출합니다.현재 클래스에 이 방법이 없다면, 조상의 체인을 따라 위로 이동합니다.아직 잘 모르겠어요.나 초 잡았어!이상한 은유를 암시하다
Imagine you’re just a kid, and that annoying Little Johnny who is trying to outsmart you asks you sheepishly: “Do you know what
.planets
are in our solar system? I bet you don’t!”.Well you actually don’t know the answer, but you wouldn’t let Little Johnny get his victory, and so you make this your life goal to find out, and you ask your parents: “What are the
.planets
in our solar system?”. And well, your parents don’t know that either, so they go on and ask their parents, who happen to know the answer.Now it’s your turn to smirk sheepishly back at Little Johnny and tell him what the answer is.
So now whenever someone asks you what are the
.planets
in our solar system, you have the answer, from your Grandparents.
이게 무슨 상관이야?우리는 방법 찾기가 어떻게 작동하는지 토론했다. 나의 last post 중에서 나는 사용
Module
, include
, extend
중용 방법prepend
을 토론했다.이제 당신include
, extend
, prepend
의 모듈을 볼 때 각자의 조상 사슬을 봅시다.Awesome = Module.new
class IncludeModule
include Awesome
end
IncludeModule.ancestors #=> [IncludeModule, Awesome, Object, Kernel, BasicObject]
class ExtendModule
extend Awesome
end
ExtendModule #=> [ExtendModule, Object, Kernel, BasicObject]
# WHERE IS THE MODULE?!
class PrependModule
prepend Awesome
end
PrependModule.ancestors #=> [Awesome, PrependModule, Object, Kernel, BasicObject]
너는 이상한 일을 발견할 수 있을 것이다.include
과prepend
반대;그것은 이전에 삽입된 적이 있기 때문에, 기술적으로 말하자면, 너는 여전히 그것을 호출할 수 없다.include
하나의 모듈을 사용할 때 클래스에 접근할 수 있다는 것을 알고 있다. 우리는 방법의 호출이 조상의 체인을 통해 이루어진 것을 알고 있다. 그러나.모듈이 조상 체인에 없으면 extend
어떻게 작동합니까?Ruby에서 Singleton류라고 하는 것(때로는
extend
, Metaclass
또는 Anonymous Class
Ruby에서 클래스를 초기화할 때마다 두 개체 Eigenclass
자체 및 Foo
가 생성됩니다.이를 증명하기 위해 나디아는 자신의 강연에서 현재의 클래스를 검사하는 좋은 방법을 보여 주었다.Foo’s Singleton Class
는 기본적으로 메모리의 현재 활성 루비 객체와 상호 작용하는 방식입니다.ObjectSpace.count_objects[:T_CLASS] #=> 920
Foo = Class.new
ObjectSpace.count_objects[:T_CLASS] #=> 922
지금 우리가 ObjectSpace
가 무엇을 하고 있는지 이해하기 전에 먼저 ObjectSpace
를 이해해야 합니다. 내 말을 참고 다음 절을 완성하면 extend
의 마력을 이해할 수 있습니다!외동 자녀 반에 관한 거.
Singleton Class
대체명칭extend
과 마찬가지로 익명이기 때문에 조상사슬에 나타나지 않는다(!!!)이것은 우리가 singleton 클래스에 접근할 수 없다는 것을 의미하지는 않지만, 사실상 우리는 Singleton Class
라는 간편한 방법을 사용할 수 있다.class Foo
end
Foo.singleton_class #=> #<Class:Foo>
방금 만든 클래스 Anonymous Class
가 무엇인지 봅시다.class Foo
end
Foo.class #=> Class
다음과 같이 초기화 클래스를 대체하는 방법도 있습니다.Foo = Class.new
지금은 익숙해 보이지 않습니까?Foo는 클래스의 인스턴스입니다.왜 이게 중요해?이것은 현재
.singleton_class
에서 실행 중인 일반적인 방법이 사실상 .class
의 실례적인 방법이라고 생각하기 때문이다그것이 효과가 있는 이유는 Foo
Class
의 실례이기 때문이다!우리는 지금 단례류가 조상의 사슬에 보이지 않는다는 것을 안다.체인에 또 안 보이는 거 기억나?모듈을 만들 때
Foo
!우리는 단례류 자체의 조상 사슬을 검사할 수 있다.
HiddenModule = Module.new
class Foo
extend HiddenModule
end
Foo.singleton_class.ancestors #=> [#<Class:Foo>, HiddenModule, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
# Well HiddenModule is not so hidden anymore!
우리가 알고 있는 Class
은 실제로singleton류의 실례적인 방법일 뿐이라는 것을 증명할 수 있다.module Mystery
def resolved?
true
end
end
class Foo
extend Mystery
end
Foo.resolved? #=> true
Foo.singleton_class.instance_methods.grep(/resolved?/) #=> [:resolved?]
Foo.method(:resolved?) #=> #<Method: Class(Mystery)#resolved?>
현재 우리는 extend
배후에서 실제로 무엇을 했는지 알고 있다. 기본적으로 class_method
단례류 자체에 있다.증명합시다!class Bar
Bar.singleton_class.include Mystery
end
Bar.resolved? #=> true
Bar.singleton_class.instance_methods.grep(/resolved?/) #=> [:resolved?]
Bar.method(:resolved?) #=> #<Method: Class(Mystery)#resolved?>
여전히 유효합니다!하지만 그렇습니다. 완전한 폼을 쓰는 데는 놀라운 세 글자가 필요합니다. 이것은 매우 큰 작업이기 때문에 우리는
extend
키를 절약할 수 있습니다!저자 설명
더 많은 글을 뽑을 테니
include
, extend
, included
연결에서 제 last post 를 보세요!아이고, 이것은 나의 두 번째 박문이다.더 많은 학습과 공유를 기대합니다!
Reference
이 문제에 관하여(루비는 방법이 없어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/edisonywh/ruby-has-no-class-methods-39l5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)