Rubyクラスメソッドがありません
待って.whaaaaaaaaaaaaaaaaaaaat?
私はあなたのことを知りません、しかし、私が最初に聞いたとき、それは私の正確な反応でした
Nadia Odunayo
’sの話RubyConf KL 2018
(心は、私が今まで聞いた中で最も魅惑的な話の一つ!)そのルビーにはクラスメソッドがないことを示した.Rubyを初めて学び始めたとき、Rubyは基本的に二つのタイプのメソッドを持っていると言われました.
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がクラスメソッドを持っていないと言ったとき、私は何を話していますか?
両親。祖父母。祖先..
私たちが理解する必要がある最初のものはルビーの祖先鎖と呼ばれるものです.
先祖の鎖はルビーがどのように働くかを理解するのに不可欠ですチェーンを呼び出している全体のメソッドはチェーンのために働きます、しかし、ここで、私は過度に簡単な説明を試みます.
Rubyではすべてが継承する
Object
, あらゆるObject
Aから継承する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)
メソッドを呼び出すと、現在のクラスのメソッドを呼び出します.現在のクラスがそのメソッドを持たない場合、それが1つを見つけるまで、それは祖先鎖を遡ります.まだ明確?私はgotchu!奇妙な比喩
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
) with include
, extend
and prepend
. では、それぞれの祖先チェーンを見てみましょうinclude
, extend
and 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
モジュールは、クラスメソッドへのアクセスを取得し、また、メソッドの呼び出しは、祖先鎖を介して発生することを知っているが、..どうしたらextend
モジュールが先祖鎖にない場合は動作しますか?その理由は、Singletonクラスと呼ばれるRubyの何かのためです
Metaclass
, Anonymous Class
or Eigenclass
)Rubyクラスを初期化するたびに、2つのオブジェクトが生成されます.
Foo
そしてFoo’s Singleton Class
. これを証明するために、彼女の話で、ナディアは、使用しているクラスの現在のカウントを調べる素晴らしい方法を示しましたObjectSpace
. ObjectSpace
基本的には、メモリ内のすべての現在の生きているRubyオブジェクトと対話する方法です.ObjectSpace.count_objects[:T_CLASS] #=> 920
Foo = Class.new
ObjectSpace.count_objects[:T_CLASS] #=> 922
今、何を理解する前にextend
している、我々は最初に理解する必要がありますSingleton Class
, だから、私と一緒に、次のセクションを取得し、我々はその後、理解することができますextend
マジック!シングルトンクラスについて
Singleton Class
, 別名のようにAnonymous Class
このようにして、アノニマス型のチェーン(!!!)では匿名であることが示唆されています.それは私たちがシングルトンクラスにアクセスできないことを意味しません.singleton_class
我々が使うことができるそれ.class Foo
end
Foo.singleton_class #=> #<Class:Foo>
何を見てみましょう.class
クラスのクラスを作成します.class Foo
end
Foo.class #=> Class
以前にも気づいたかもしれませんが、以下のようにクラスを初期化する方法もあります.Foo = Class.new
今は本当に身近なルックス?fooはクラスのインスタンスです.なぜこれが重要ですか?これは、あなたが実行していると思うようになった通常のクラスメソッドを意味するからです
Foo
実際には、インスタンスメソッドClass
. — それは働くFoo
のインスタンスClass
!私たちは、Singletonクラスが祖先鎖で見えないということを知っています.他のチェーンに表示されなかった覚えていますか?モジュールを使用すると
extend
! Singletonクラス自体の祖先鎖をチェックすることができます.
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_method
, 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
実際にシーンの後ろには基本的にはinclude
Singletonクラスそのものについてそれを証明しましょう!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?>
まだ動作!しかし、ええ、完全な形を書くことは驚異的な3つの語を必要とします
extend
代わりにキーストローク私たちを救うために!著者注
私はいくつかのより多くの記事をポンピングアウトしますlast post on
included
, extended
and prepended
フック!Phew、それは私の2番目のブログのためのそれです.を楽しみにして共有を学ぶ!
Reference
この問題について(Rubyクラスメソッドがありません), 我々は、より多くの情報をここで見つけました https://dev.to/edisonywh/ruby-has-no-class-methods-39l5テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol