Ruby
で「自己」を理解する今日はself
についてお話したいと思います。 Rubyをしばらくプログラミングしているなら、self
というアイデアを内面化している可能性があります。 プログラムを読んだり書いたりするたびに、self
はあなたの心の奥にあります。
しかし、経験の少ないRubyistsのために、self
は困惑することができます。 常に変化していますが、コードに明示的に表示されることはありません。 あなたは知っていることが期待されています。
初心者が直面する多くの問題は、self
を理解していないことによって引き起こされます。 インスタンス変数を「失った」場合や、mixinに表示されているデータに困惑したことがある場合は、そのコンテキストでself
を理解していなかったためです。
この記事では、毎日のさまざまな状況でself
を見ていきます。
自己とは何ですか?
Rubyのすべてがオブジェクトであると人々が言うのを聞いたことがあるかもしれません。 それが本当なら、あなたが書いたコードのすべての部分があるオブジェクトに”属している”ことを意味します。
self
は、現在実行中のコードを”所有”するオブジェクトを指す特別な変数です。 Rubyはself
を使用しています。:インスタンス変数のための
- :
@myvar
- メソッド、クラス、およびモジュールを定義するときのメソッドと定数ルックアップ
- 。
理論的には、self
はかなり明白です。 しかし、実際には、トリッキーな状況がポップアップするのは簡単です。 それが私がこの記事を書いた理由です。
自己の例
ここではいくつかの例をステップスルーします。 最初のものはあなたのためにあまりにも基本的なように見える場合は、ちょうど読み続 彼らはより高度になります。
インスタンスメソッドの内部
以下のコードでは、reflect
はインスタンスメソッドです。 これはGhost.new
で作成したオブジェクトに属します。 そのため、self
はそのオブジェクトを指します。
class Ghost def reflect self endendg = Ghost.newg.reflect == g # => true
この例では、クラスメソッド
の内部では、reflect
はGhost
のクラスメソッドです。 クラスメソッドでは、クラス自体がメソッドを”所有”します。 self
はクラスを指しています。
class Ghost def self.reflect self endendGhost.reflect == Ghost # => true
これは、モジュール内の”class”メソッドと同じように動作します。 例えば:
module Ghost def self.reflect self endend Ghost.reflect == Ghost # => true
Rubyでは、クラスとモジュールはオブジェクトとして扱われることを覚えておいてください。 したがって、この動作は、最初の例で見たインスタンスメソッドの動作とそれほど違いはありません。
クラスまたはモジュール定義の内部
Railsのようなフレームワークに適したRubyの特徴の一つは、クラスやモジュール定義の中で任意のコードを実行できることです。 クラス/モジュール定義の中にコードを置くと、他のRubyコードと同じように実行されます。 唯一の本当の違いはself
の値です。
以下に示すように、self
は定義中のクラスまたはモジュールを指しています。
class Ghost self == Ghost # => trueend module Mummy self == Mummy # => trueend
mixinメソッドの内部
Mixed-inメソッドは、self
に関しては、”通常の”インスタンスまたはクラスメソッドと同じように動作します。 これは理にかなっています。 それ以外の場合、mixinはあなたがそれを混合したクラスと対話することができません。
インスタンスメソッド
reflect
メソッドがモジュールで定義されていても、そのself
は混合されたクラスのインスタンスです。
module Reflection def reflect self endend class Ghost include Reflectionendg = Ghost.newg.reflect == g # => true
クラスメソッド
クラスメソッドを混在させるクラスextend
の場合、self
は通常のクラスメソッドとまったく同じように動作します。
module Reflection def reflect self endend class Ghost extend ReflectionendGhost.reflect == Ghost # => true
メタクラス
の中で、一度に多くのクラスメソッドを定義するためのこの一般的なショートカットを見たことがあるでしょう。
class Ghost class << self def method1 end def method2 end endend
class << foo
構文は実際にはかなり興味深いものです。 オブジェクトのメタクラスにアクセスすることができます-これは”singleton class”または”eigenclass”とも呼ばれます。”私は将来のポストでより深くメタクラスをカバーすることを計画しています。 しかし、今のところ、メタクラスはRubyが特定のオブジェクトに固有のメソッドを格納する場所であることを知る必要があります。
class << foo
ブロック内からself
にアクセスすると、メタクラスが取得されます。
class << "test" puts self.inspectend# => #<Class:#<String:0x007f8de283bd88>
任意のクラスの外部
任意のクラスの外部でコードを実行している場合、Rubyはまだself
を提供します。 それはのインスタンスである”main”を指しますObject
:
puts self.inspect # => main