Rubyでどのようにシングルトーンを作成しますか?

Rubyでシングルトンを作成する方法は?
個人的には、4つの方法が思い浮かびます。


画像


方法1:シングルトンを含める


標準ライブラリは、以下を生成するSingletonモジュールを定義します
クラスに対するいくつかのアクション、特に:



これは古典的なシングルトン実装だと思います。 とにかく、私は書くだろう
そのような何か、私はJavaプログラマーになります。 特別なことは何もありません。すべて機能します。


方法2:module_functionを持つモジュール


Moduleは、使用できる#module_functionメソッドがあります
自己定義メソッド。 このアプローチは、たとえば、
Math 例:


 module M module_function def f :f end end Mf # ==> :f 

いくつかの理由から、このようなシングルトンの実装はお勧めしません。



ところで、同じ目的でextend selfを使用extend self代わりに
module_function 。 これにより、プライベートメソッドの問題が解消されます。 しかし、言いましょう
悪名高いruby-style-guideはこのアプローチを承認していません(リンク:
https://github.com/bbatsov/ruby-style-guide#module-function


extend self動作が異なることは明らかだと思いますが、
いくつかの危険な違い。


更新しました。 まだあまり明らかではありません。 extend selfは、モジュールを接続されたモジュールのリストに追加することを強制し(書き込みがどれほど簡単かはわかりません)、 module_functionはメソッドのコピーを作成します。 具体的には、コードを見てください:


 module M module_function def f :f end end class A include M end Mf # ==> :f # module_function     include A.new.send(:f) # ==> :f module M def f :TROLOLO end end A.new.send(:f) # ==> :TROLOLO Mf # ==> :f 

方法3:クラスメソッドのみのクラス/モジュール


 class MyClass def self.f :f end def self.g :g end end MyClass.f # ==> :f 

または:


 class MyClass class << self def f :f end private def g :g end end end MyClass.f # ==> :f MyClass.g # ==> NoMethodError 

もちろん、 class代わりにmoduleを使用できます。 上記で
スタイルガイド、このアプローチは推奨されません。 代わりにお勧め
module_function


私の実践では、このアプローチが最も頻繁に遭遇しました。 個人的に、彼はいつも私に見えた
ある種の恐ろしい松葉杖ですが、同時に使用するよりも好きです
Singleton 、として MySingleton.do_somethingは私にとってより魅力的に見える
MySingleton.instance.do_something


Objectのインスタンスを作成します


最近、私は常にこのアプローチを使用しています:


 MySingleton = Object.new class << MySingleton def f g end private def g puts 'hello' end end 

これで、シングルトンは必要なメソッドを備えたObject単なるインスタンスになりました。


 MySingleton.class # ==> Object 

ここに問題があります:



小さな余談:クラス<<自己


私は誰もが構文を見たと思う:


 class MyClass class << self def do_something_on_class ... end end def do_something_on_instance ... end end 

同時に、私は人がこれが何を意味するか知らないことに繰り返し気づきました
建設。 実際、Rubyでは、オブジェクトには実際に2つのクラスがあります。
そのインスタンスと、いわゆる 「シングルトンクラス」-シングルトンクラス。


確かに、オブジェクトにメソッドを直接定義する例を見ました。
このようなもの:


 x = Object.new def x.hey 'hey' end x.hey # ==> 'hey' 

クラス指向のOOPでは、オブジェクトに独自のメソッドはありません。 オブジェクトの動作
それが属するクラスによって決定されます。 したがって、決定できません
def x.heyを使用してオブジェクトのメソッド、クラスで定義する必要があります。 ここに
これを行う場合にのみ、 Objectすべてのインスタンスは
望んでいない#heyメソッドを取得します。 したがって、Rubyは「追加」を作成します
シングルトンクラスと呼ばれるオブジェクトのクラス。 メソッドを使用して取得できます
#singleton_class 。 一般的に、私は夢中になり、おそらくそうしなかった人だけを混乱させました
「シングルトンクラス」について知っていました。 これはRubyの非常に興味深い部分なので、お勧めします
それについて自分で読んでください。


実際には、要するに、 class << some_objectの構築class << some_objectclass << some_object 「入ります」
シントン。 比較する:


 class A # enter class A scope def hey 'hey' end end class << A # enter class A singleton class scope def hey 'hello' end end A.new.hey # ==> 'hey' A.hey # ==> 'hello' 


Source: https://habr.com/ru/post/J340006/


All Articles