Ruby言語のクラス定義に関する質問

このQ&Aのポイント
  • Ruby言語におけるクラス定義について質問です。Class.new()を使用してデフォルト引数を持つクラスを生成する場合、公式のリファレンスによれば、無名クラスが生成されます。この無名クラスはメタクラスと同義でしょうか?また、メタクラスはClassクラスのインスタンスであると言えるのでしょうか?
  • Class.new()メソッドを使用してデフォルト引数のあるクラスを生成する場合、Rubyでは無名クラスが生成されます。無名クラスはYUGUIさんのサイトの画像にあるメタクラスと同様のものでしょうか?また、メタクラスはClassクラスのインスタンスということになるのでしょうか?
  • Ruby言語でClass.new()を使用してデフォルト引数を持つクラスを生成する場合、無名クラスが生成されます。無名クラスはメタクラスと同じ意味合いを持つのでしょうか?また、メタクラスはClassクラスのインスタンスであると言えるのでしょうか?
回答を見る
  • ベストアンサー

Ruby言語に関して質問です。

Rubyで、クラス定義の際の質問です。 通常 cattle= Class.new(); で引数がデフォルトの場合は、Objectクラスのサブクラス生成すると 公式のリファレンスに記述があります。 調べてみると上記コードの場合は,cattleという無名クラスと呼ばれるものになるそうです。 この無名クラスとはYUGUIさんのサイトにある http://yugui.jp/images/uploaded/20084013-metaclass.png 右端の列にあるメタクラスと呼ばれるものになるのでしょうか? (無名クラス と メタクラスは同義??) また上記URLの画像からメタクラスはClassクラスのインスタンスであるようです。 ただClass.newで実行される newというクラスメソッドってサブクラスを生成すると いうふうにリファレンスにありますがレシーバであるClassクラスのインスタンスを 返すという記述はありません。 ただ、おそらくメタクラスというのはClassクラスのインスタンスなのだとは思いますが、 この理由はなぜなのでしょうか? もう一点、p Cattle.class();と記述すると Classクラスが返ると思います。これはCattleクラスのClassクラスのインスタンスである ということになるのでしょうか? しかしながらYUGUIさんの画像ではCattleはメタクラスのインスタンスとなっています。 であれば、メタクラスを意味するのでしょうか? 公式リファレンスには、上記に書いたような関係はRubyを扱う際には特に問題ではないとありますが、気になっています。

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

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.1

>(無名クラス と メタクラスは同義??) 無名クラスとメタクラスは直接は関係ありません。Yuguさんは、Classクラスオブジェクトの特異クラスのことをメタクラスと呼んでいるようですね。特異クラスは一般に無名クラスですが。 >また上記URLの画像からメタクラスはClassクラスのインスタンスであるようです。 特異クラスであろうが、メタクラスであろうが、すべてのクラスはClassクラスのインスタンスです。 理由は無いというか、それがRubyのクラスの概念です。数学で言う公理みたいなものか。 >もう一点、p Cattle.class();と記述するとClassクラスが返ると思います。 Classという定数が返りますが、これはClassクラスのことですね。 >これはCattleクラスのClassクラスのインスタンスであるということになるのでしょうか? 日本語がおかしいです。 Cattleという定数に代入されているのは、Classクラスのインスタンス(のリファレンス)であると言うことです。わかりやすく言うと、CattleというのはClassクラスのインスタンスということ。 >しかしながらYUGUIさんの画像ではCattleはメタクラスのインスタンスとなっています。 であれば、メタクラスを意味するのでしょうか? 図のしたの↓は読みましたか?理解できましたか? Yugui>つまり、初期状態ではメタメタクラスというものは定義されていないんだな。メタクラスに対して特異メソッドを定義しようとしたとき、初めてメタメタクラスみたいなものが作成されて、 一般に、クラスAのインスタンスXに特異メソッドを定義すると、「Xの特異クラス」が作られて、XはAのインスタンスで無く、Aのサブクラスである「Xの特異クラス」のインスタンスに変わります。これは特異メソッドや特異クラスの説明の所に書いてあるはず。 で、classメソッドで返る値では特異クラスのことは隠されます。うーん、このこと、Object#classのリファレンスに書いてないですね。 上の文のA←Class、X←Cattle とするとあの図の関係になりますね。「メタクラス=Classクラスインスタンス(ここれはCattle)の特異クラス」なので、Xの特異クラスのことをメタクラスと呼んでいるわけです。 基本的な理解のためには、「メタクラス」という言葉を頭の中から一度追い払って、「クラス」「特異クラス」だけで考えるといいと思いますよ。 特異クラスというものを十分理解してから、「メタクラス=クラスの特異クラス」と覚えるといいかと。

egoist1209
質問者

お礼

ありがとうございます。 とりあえず、ひととおりCGI的な処理が作れればいいので まずは、ざくっと使えるようになるまでは深く突っ込まないようにします。

関連するQ&A

  • 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の継承関係について質問いたします。

    Rubyのクラスの継承関係について質問です。 RubyではすべてのクラスはObjectクラスが親クラスとなっていると思います。 そこで p File.class; と記述して実行すると FileクラスがClassクラスとして表示されます。 FileはFileクラスのはずなのになぜClassクラスなのでしょうか? そして最上位のクラスであるObjectクラスも p Object.class; とすると Classクラスと出力されてしまいます。 なぜなのでしょうか??? p Class.class; と記述するとClassクラスと出力されました。 もうわけがわかりません。 どなたかご教授ください。お願いします。本気でド壷中です。

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

    下記のコードについてです。 Runnableがインスタンス化されていますが、 どうしてそれが可能なのかが分かりません。 分からない点は 1.Runnableはインタフェースであるから、本来、直接インスタンス化は不可能であるはず。 2.しかし、Runnableはクラスライブラリjava.langパッケージに含まれている。 だからインスタンス化は可能なのかもしれない。 3.あるいは、下記のコードではメソッド内の無名クラスであるから、「new Runnable(){」の 部分でスーパークラスとしてのRunnableを継承したサブクラスを生成しているのかもしれない。 アドバイスをよろしくお願い致します。 public class Main{ public static void main(String[]args){ Runnable task = new Runnable(){ public void run(){ System.out.println("run"); } }; Thread thread = new Thread(task){ public synchronized void start(){ System.out.println("start"); } }; thread.start(); } }

    • ベストアンサー
    • Java
  • オブジェクト指向について質問

    メインのクラスをインスタンスする際にコンストラクターに書かれている処理が実行されますが、オブジェクトが生成された時のイベントに書くのと、どのような違いがありますか? public partial class Form1 : Form{ public Form1()//コンストラクター {処理1} private void Form1_Load(object sender, EventArgs e)//インスタンス時のイベント {処理2} } また、別クラスの中でnewを使ってインスタンスがされ場合、コンストラクターと上記のイベントは同じように発生しますか? public class Form2{ Form1 = new Form1(); } よろしくおねがいします。

  • rubyのクラス変数のようなものは無い?

    rubyのクラス変数に相当するものはPHPにはないのでしょうか? つまり、あるクラスの全てのインスタンスで共有する変数です。 DB中に存在する環境固有の値をクラスで保持したいのですが、インスタンスごとにDBアクセスするのは無駄なので、初回インスタンス生成時(is_nullで判断)にのみDBアクセスして、あとはそれを参照するだけにしたい。 globalを使って全体でのグローバル変数にするしかないのでしょうか?

    • ベストアンサー
    • PHP
  • JAVA初心者です。

    javaにおけるprivateメンバの動きについて伺いたいことがございます。 基本的にスーパークラスのprivateなメンバへはメソッド・フィールドともにサブクラスからは アクセスできないとのことですが、 例えば、以下のようなコードがあるとします。 //スーパークラスの定義 class SuperClass{ private String privateString = "スーパークラスのプライベートメンバ"; public void getter(){ System.out.println(this.privateString); } } //サブクラス class SubClass extends SuperClass{ } //実行クラス class RunClass { static public void main (String args []){ SubClass subObj; subObj = new SubClass(); subObj.getter(); } } 上記のようなコードの場合サブクラスのインスタンスであるsubObjが スーパークラスのpublicなメソッドを通じてサブクラスからスーパークラスのprivateメンバへアクセスが できてしまっています。 これは、スーパークラスのprivateが隠蔽されていないのではないでしょうか? 果たして、このときいったサブクラスのインスタンスのsubObjはどういった動きをしているのでしょうか?

    • ベストアンサー
    • Java
  • 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
  • サブクラスで.newInstance()でインスタンス化できない

    以下のようにClass.forNameで取得したクラスをインスタンス化 しようとしていますが、できません サブクラスは.newInstance()でインスタンス化できないのでしょうか? 代替の方法はありますか? ーーーーーーーーーーーーーーーー public class test4121 { public static void main(String[] args) throws Throwable { new test4121(); } public test4121() throws Throwable { //これは実行できるが test4121_2 test = new test4121_2(); //これはできない Class.forName("test4121$test4121_2").newInstance(); } class test4121_2{ } } ーーーーーーーーーーーーーーーー

  • 書籍 メタプログラミング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
  • 【Ruby】Protectedの確認プログラム

    こんにちは、Ruby初学者です。 以下の問題が解けずに困っています。「protectedが、メソッドをクラス内部から使えるようにする。また、同一クラス内ではインスタンスメソッドとしても使えるようにする。」という教科書的な内容は理解しているつもりでプログラムを書くのですが、どうも上手くいきません。 ヒントだけでも構いませんので、諸兄姉の知識をお貸しいただければ幸いです。 「protectedと宣言されたメソッドは、そのメソッドが定義されているクラスのサブクラスで定義されているメソッドから、メッセージの送信元とは異なるオブジェクトに対しても呼び出せることを確認するプログラムを作成し、結果を説明せよ。」 よろしくおねがいいたします。

    • ベストアンサー
    • Ruby

専門家に質問してみよう