クラス定義内のselfについて疑問

このQ&Aのポイント
  • 書籍『メタプログラミングRuby』のP143には、クラス定義内でのselfについての記述があります。
  • クラス定義内には、カレントオブジェクトselfとインスタンスメソッド内のselfが存在します。
  • 質問者は、なぜクラス定義内でのselfという表現が用いられるのか疑問に感じています。
回答を見る
  • ベストアンサー

書籍 メタプログラミングRubyの中の一文

上記書籍のP143の カレントクラスについて質問です。 上記書籍に、 【クラス定義のなかでは、カレントオブジェクトselfは定義されたクラスである】 という記述がありますが 例えば、以下のようなクラス定義あがあるとします。 class Test print self.class def self.method_01() print "メソッド01" end def method_02() return self end end クラス定義内に3箇所selfが存在しますが、 インスタンスメソッド の method_02()内のselfはnewメソッドによって 作成されたTestクラスのインスタンスの意味だと思います。 それより上の二つのselfは確かに定義中のカレントオブジェクト・・つまりTestクラス ですけれど、なぜ書籍では、クラス定義内でのselfという表現なのでしょうか? 個人的には、【クラス定義内で定義されるインスタンスメソッド内にあるselfを除くselfはカレントオブジェクトである】という風に、説明すべきだと思うのですが 何か私の解釈に誤りがあるのでしょうか?それとも、文面を気にしすぎなだけでしょうか? くだらない質問ですがご意見をおきかせください。

  • Ruby
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10256)
回答No.2

解釈としては間違ってないです。 「クラス定義の中で~」の文章を、「メソッド定義の中で~」が上書きする形で、別の意味を与えていると思えば良いと思います。 「クラス定義のコンテキストの中で」の略記と考えた方が良いか。

その他の回答 (1)

回答No.1

>クラス定義内で定義されるインスタンスメソッド内にあるselfを除くselfはカレントオブジェクトである selfは常にカレントオブジェクトですよ。 ひとつめ、ふたつめのselfは「クラス定義の中」なのでselfは定義されたクラス(クラス名)を返す。 みっつめは「メソッド定義の中」なのでselfはレシーバを返す。 「メタプログラミングRuby」は持っていませんが、そのすぐ後のページにメソッド定義の中のselfの話があるのでは?

1000vicki
質問者

お礼

ああ・・なるほど、定義したクラスからnewしたインスタンスで実行するインスタンスメソッド内のselfは、これも実行中のインスタンスメソッドからすれば同じくカレントオブジェクトということですか・・・。 なるほど・・・・。

関連するQ&A

  • Module#method_addedの挙動

    すいません、Rubyのドキュメントを見ながら動作を追っていて、疑問に感じたので質問をさせてください。 Module#method_addedというメソッドが追加されたタイミングで動作するメソッドがあります。 定義場所がModuleクラスの中なので、Moduleにメソッドを追加したら、それがmethod_addedを呼び出すと思って試して見たのですが、何故かそうなりません。 何故なのか理由がわからないんですが、教えていただけないでしょうか? ------------------------------------------------------------------ class Object def self.method_added(*_) p self.class.name p __method__ p _ end def self.singleton_method_added(*_) p self.class.name p __method__ p _ end end class Module def self.method_added(*_) p self.class.name p __method__ p _ end def self.slngleton_method_added(*_) p self.class.name p __method__ p _ end end module Foo def self.foo end def foo2 end end class Bar def self.bar end def bar2 end end ------------------------------------------------------------------ 出力結果 ------------------------------------------------------------------ "Class" :singleton_method_added [:bar] "Class" :method_added [:bar2] ------------------------------------------------------------------ 動作環境は、Mac rubyのバージョンは2.4.0です。 ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]

    • ベストアンサー
    • Ruby
  • Ruby 特異メソッドのnewが先に実行?

    Rubyのインスタンス生成について質問があります。 通常クラスを定義する場合は class Hoge ; def hello(); pirnt "hello"; end であると思います。 ただ Hoge = Class.new(); でもクラスは定義できるとききました。 ただこの場合Hogeクラスに定義できるのは HogeというClassクラスから作られた特異クラスとしてのHogeに 特異メソッドのみを定義できるということですよね? 通常のインスタンスメソッドは定義できませんよね? ではでは、 hoge = Class.new(); とした場合はどうなるのでしょうか? この場合は Classクラスの純粋なインスタンスとなるのでしょうか? 前者の定義とおなじ仕方ですが代入先が、通常の変数です。 この場合は、クラスオブジェクトとして生成されるのですか? オンラインマニュアルをみたところ 「新しく名前の付いていない superclass のサブクラスを生成します。 superclass が省略された時にはObject のサブクラスを生成します。 名前のないクラスは、最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。」 とあります。 上記内容は Classクラスの特異クラスとして定義されている特異メソッド(new)です。 これは Class.new()で作られたインスタンスを代入する先が定数であればその定数名と同じクラスを定義しつつそのClassクラスのクラスオブジェクトを生成するという意味合いでまちがいないでしょうか? 上記のとおりであれば hoge =Class.new()の場合は、やはりhogeというクラスを定義することになるのでしょうか? クラス定義は定数でなければならないはずですよね。 ただ実際、 p hoge;として出力すると#とひょうじされています。これはhogeがクラスオブジェクトではなく ただのインスタンスであるということでしょうか? であるならばこの hoge = Class.new()の式のnewはClassクラスオブジェクトに定義された特異メソッドではなく Classクラスに定義されたnewメソッド・・・・・つまりClassクラスに定義されたインスタンスメソッドの方のnewメソッドだとおもうのですが・・・・・・。 つまりこちらのメソッドですね。 「new( ... ) クラスのインスタンスを生成して返します。このメソッドの引数はブロック引数も含め initialize に渡されます。」 ※オンラインリファレンスから参照しました。 しかし 通常メソッドの検索は特異メソッドからはじまりその後クラスのインスタンスメソッド->親クラスのメソッドと 検索して行くとあります。 必ず先に、特異メソッドを実行しているはずだと思うのですが・・・。 やはり特異メソッドnewを実行しているのでしょうか? 長々すみませんが、ご教授ください。

    • ベストアンサー
    • Ruby
  • Ruby インスタンスの初期化について

    newメソッドを使わずにinitializeメソッドを定義しただけで インスタンスが作成されて初期化までされる理屈について 教えていただけないでしょうか? またクラスを作るときに基となっているObjectクラスとは一体 何物なのか、教えて頂きたい。 例 01:#Sampleクラスを作る 02:class Sample 03: #Samlpeクラスのインスタンスを初期化 04: def imitialize( lv, hp ) 05: end 06:end ↑の場合インスタンスlvとhpは、「lv = sample.new( 0 )」などと言う ように定義されてない。 それにnewメソッドでインスタンスを作りそこに数値の0を代入できるなら そもそもinitializeで初期化する必要は無いのではないでしょうか? 有識者の方いらっしゃいましたら、ご説明をよろしくお願いします。

    • ベストアンサー
    • Ruby
  • インスタンス内から自分のクラス名を取得する方法

    クラスインスタンス内から自分のクラス名を取得しようと思うと、self.class.nameで取得できますが、type.nameでも取得できます。 しかし、typeは非推奨メソッドとなっているため、警告が出て、このままでは使用することができません。 素直にself.classを使えばいいのかもしれませんが、selfのワンクッションがどうにも気に入りません。 スマートな記述方法あったら教えて下さい。 # self.class.nameを使用する場合 class MyClass  def print_classname   puts self.class.name   # puts class.name これはエラー  end end # type.nameを使用する場合 class MyClass2  def print_classname   puts type.name # これはdeprecatedの記述で警告が出る  end end

  • ブロック1 Ruby認定試験対策問題

    Ruby認定試験対策問題をやっていたら分からないところがあったので、 教えてください。 2.9-1.ブロック ■問題 testメソッドに渡されたブロックのselfは次のうちどれか? class Foo def test (1..3).each{|i| yield(i)} end end foo = Foo.new foo.test{|i| i } ■回答 トップレベル ■解説 ブロックはメソッドの呼出し先のselfを継承します ■疑問 ・testメソッドに渡されたブロックとは、(1..3)のことを指すのでしょうか。 ・メソッドの呼出し先とは、foo.test{|i| i }のことを意味しているのでしょうか。 ・呼出し先のselfとは、fooかFooのことでしょうか? ・「selfはメソッド内で実行されるとそのメソッドを実行しているオブジェクトを参照することが出来ます」 と別のサイトに記載されていたのですが、「トップレベルのselfとはObjectクラスのメソッドを実行している」、という意味になるのでしょうか。 それがこの問題のどこに関連しているのでしょうか。

    • ベストアンサー
    • Ruby
  • Rubyのsuperclassメソッドについて

    Rubyについての質問です。処理系は1.8.7です。 class Foo def initialize(a) @a = a end end のようなクラスを作成し、そのインスタンスを foo = Foo.new(1) のように作成します。 このとき、 foo.superclassを呼び出すと NoMethodError: undefined method `ancestors' for #<Foo:0x2b691220cc88 @a=1> とエラーになります。 一方で class FooExt < Foo def initialize (a,b) @b = b super a end end のようにFooを継承したクラスを作り、 fooext = FooExt.new(1,2) fooext.superclass とすると => Foo とsuperclassメソッドが動作します。 このsuperclassメソッドはどこで追加されたものなのでしょうか?

  • Rubyのクラス

    class Test def initialize @ary = Array.new(size){false} end def print _print end def _print print"#{@ary}" end end test = Test.new(5) test.print 上記のプログラムはエラーが出て実行できません。期待している動作は[false,false,false,false,false]です。どうしてエラーが出るか教えていただきたいです。また、解決策もよろしくお願いします。

    • ベストアンサー
    • Ruby
  • クラスメソッドのインスタンスメソッドからの呼び出し

    クラスメソッド“say”を定義しました。 クラス外からこれを呼び出すときは Hoge.say 'hello' で、同じクラス内の、インスタンスメソッド“hello”からクラスメソッド“say”を呼び出したいとき、クラス外から呼び出すのと同じように呼び出すことはできました。 class Hoge  def self.say(word)   puts word  end  def hello   Hoge.say('hello')  end end しかし、メソッド“hello”内にHogeというクラス名を直書きしたくないのですが、どんな文法を使用すればよろしいでしょうか? # Hoge#hello内での試行錯誤 self.say 'hello' => エラー say 'hello' => エラー ひょっとして、クラス名を直書きする以外手段はないのでしょうか・・?

    • ベストアンサー
    • Ruby
  • Ruby 文法 ブロックの中で メソッドを呼ぶ

    class Hoge def val 'aaa' end def piyo yield end end h=Hoge.new h.piyo do p h.val #<ーここの話 end 上の様に書く時、ブロックの中で、そのクラスのメソッドを呼ぶ時、上の例だと h.val と書いてますが、これself.valなどと書きたいのですがERRになってしまいます。 h.と書くのがとても嫌なのですが、なにか良い書き方あるのでしょうか?

    • ベストアンサー
    • Ruby
  • singletonメソッドへのアクセス

    インスタンスメソッドからsingletonメソッドへのアクセスが、思ったようにできません。 はじめは、次のように記述すれば動作すると思っていました。 (MyClass.get_hello_wordをインスタンスメソッドから呼び出し) class MyClass  def hello   puts self.get_hello_word # エラー発生源  end  def self.get_hello_word   'hello every one'  end end MyClass.new.hello # エラー しかし、実際には次のように記述しなければ動きませんでした。 class MyClass  def hello   puts self.class.get_hello_word # self.classのワンクッション  end  def self.get_hello_word   'hello every one'  end end MyClass.new.hello そもそも、 def self.get_hello_word と定義したんだから、参照する時も同様にできてもいいのではないかと思うんですけれど、何か認識が間違っているのでしょうか。 だとしたら、(勘で言いますと) class << MyClass  def get_hello_word   'hello every one'  end end の文法の考え方がからんでいるような気がするのですが・・ ちんぷんかんぷんです。 どうかこの辺りの知識を教えて頂けないでしょうか。 あと、self.class.get_hello_wordの記述方法よりも簡単な(そうすべき)書き方があれば教えて下さい。

    • ベストアンサー
    • Ruby

専門家に質問してみよう