質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

3回答

3206閲覧

rubyにおけるメソッドにselfを明示的に宣言する挙動について

nagane

総合スコア12

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2015/10/06 11:50

module Tekitou class Desu def nanka puts "nanka" end ​ def self.nanka? puts "nanka?" end end end ​ Tekitou::Desu.nanka? ​ Tekitou::Desu.nanka

上記のrubyプログラムを実行すると、下記の結果が帰ってきます

% ruby sample.rb nanka? sample.rb:15:in `<main>': undefined method `nanka' for Tekitou::Desu:Class (NoMethodError)

Desuクラスのnanka?メソッドにselfを付与する事によりインスタンスを作成しなくともメソッドが実行出来るようになりますが、何故このような挙動になるのか理解出来ません。
どなたか上記現象について分かりやすく説明、またはそれに準ずる事柄が解説されてる文献等ご存知でしたら、ご教授頂きたいです。

self自体は自身のオブジェクトを参照するようなもの。のような感じで、オーバーライド等によく見かけるような記法というゆるふわな認識ですが、これを付与するだけでインスタンス化しなくてもメソッドが実行出来るのは何故なのか、その辺のオブジェクトの動きが分かりません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

何か書こうと思いましたが、こちらで凄く丁寧に解説されていました。

追記
上記リンクにクラスオブジェクトという言葉が出てきますが、それが何かの説明が無かったので追記しておきます。といってもこれまた丁寧に説明されたページがあったのでリンクと引用だけ

確かにクラスはオブジェクトを生成するための雛形的なものです。しかし同時に、クラスはそれ自身もRuby実行空間に存在するオブジェクトなのです。

投稿2015/10/06 12:14

編集2015/10/06 12:25
hirohiro

総合スコア2068

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nagane

2015/10/08 08:18

ありがとうございます。こちら参考リンク拝見させて頂き、理解が進みました!
guest

0

ベストアンサー

Rubyのdefを用いたメソッド定義には二種類あります。

  1. def メソッド名(仮引数...)からはじまる(通常の)メソッド定義

nankaはこちらになります。クラスやモジュール定義内で定義した場合は、そのクラスのインスタンスメソッドになります。トップレベルで定義した場合は、どこからでも呼び出せるメソッドになります。

クラスのインスタンスメソッドとして定義された場合は、そのクラスのインスタンスを通じてしか呼び出せません。nankaを呼び出すには、Tekitou::Desuのインスタンスを作成して、それに対して呼び出す必要があります。Tekitou::Desu.new.nankaとはできますが、Tekitou::Desu.nankaとはできません。

  1. def オブジェクト.メソッド名(仮引数...)から始まる特異メソッド定義

それに対してnakna?はこちらになります。この場合は.の前にあるオブジェクトの特異メソッドになります。

つまり、self.nakan?selfの特異メソッドnanka?を定義していると言うことです。では、ここでのselfは何かというとTekitou::Desuそのものです。クラス/モジュール定義内で、かつメソッド定義外ではselfはクラス/モジュール自身になります。つまり、Tekitou::Desuの特異メソッドnanaka?を定義していると言うことです。(Rubyではクラスもオブジェクトです。Tekitou::Desuももちろんオブジェクトなので、2.パターンであると言うことです)

特異メソッドはそのオブジェクト専用のメソッドであり、そのオブジェクトを通じてのみ呼び出せます。ですので、Tekitou::Desu.nanka?と書くことが可能になっていると言うことです。

そして、このようなクラスの特異メソッドをクラスメソッドと呼びます。インスタンスに結びつかないクラスで使えるメソッドだからそのような呼び方になります。(クラスメソッドの言葉としての定義は言語によって異なるので注意してください。Rubyではこのように呼ぶと言うだけです。)

詳しくは
Ruby 2.2.0 リファレンスマニュアル > クラス/メソッドの定義
のメソッド定義、特異メソッド定義、およびクラスメソッドの定義を見てください。

投稿2015/10/06 12:21

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nagane

2015/10/08 08:16

ありがとうございました。 クラスメソッドとインスタンスメソッドの所を読んだ所腑に落ちました。 勉強不足でした・・・大変助かりました!
guest

0

Desuクラスのnanka?メソッドにselfを付与する事によりインスタンスを作成しなくともメソッドが実行出来るようになりますが、

「インスタンスを作成しなくてもメソッドが実行できる」という考え方がおかしいです。

それはさておき、

何故このような挙動になるのか理解出来ません。

クラスメソッドは、普通はクラス名.メソッド名で起動します。定義は、def クラス名.メソッド名でしますが、クラスの直下の文脈では、selfはクラス自身を意味しますので、def クラス名.メソッド名def self.メソッド名は同じです。クラス名を二度か書かなくて良いために、普通はdef self.メソッド名と書くのが好まれます。

投稿2015/10/06 12:19

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nagane

2015/10/08 08:17

ご回答ありがとうございます。ご指摘ありがとうございます > 「インスタンスを作成しなくてもメソッドが実行できる」という考え方がおかしいです。 この考え方が何故おかしいのか分からない状態で大変恐縮です。 もう少し基本的な部分を勉強していきたいと思います・・・
otn

2015/10/08 14:52

そういう言い方をする質問者は他サイト含めちょいちょい目にするので、何か初心者がはまりやすい穴がそのあたりにあるんでしょうね。 念のためですが「インスタンスを作成しなくてもメソッドが実行できる」は正しいのですが、そういう表現をするのがおかしいということです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問