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

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

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

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

Q&A

解決済

3回答

232閲覧

【Ruby】メソッドの定義について

zyno

総合スコア41

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

0グッド

0クリップ

投稿2018/07/27 06:29

編集2018/07/27 06:32

Rubyの学習においてメソッドという言葉がよく出てきます。

#1 @user = user.find_by(id: params[:id])

でいうfind_byのことをメソッドといいますが、

#2 def hello puts "hello!" end

でいうhelloのこともメソッドといいます。

これは、#1のfind_byメソッドがあらかじめRuby内で設定されているdef helloのようなもので、#2のように自作の処理をわざわざさせないために設定されているものなのでしょうか?(#1のfind_by等各種メソッドはRubyが用意してくれたライブラリ的な立ち位置?)

あと、僕の中のイメージの話なのですが、#1のメソッドはピカチュウの10まんボルトでいう10まんボルトに位置するもの(オブジェクトがメソッドを使役している感覚)で、#2のメソッドの意味は関数をイメージします。
そのため、メソッドの定義についてごっちゃになってしまっているので何とかしたいというのが質問の経緯です。

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

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

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

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

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

guest

回答3

0

ベストアンサー

Rubyのメソッドに考えるときには、メソッドの呼び出し方とメソッドの定義の仕方のそれぞれに分けて考えると分かりやすいかもしれません。

メソッドの呼び出し方について

定義の前に、メソッドの呼び出し方について説明します。メソッドの呼び出し方には3通りあります。

  • クラスがレシーバになるもの (例: File.read())
  • オブジェクトがレシーバになるもの (例: 10.to_s)
  • レシーバがないもの (例: puts("hello"))

1番目は「クラスメソッド」と呼ばれるものですね。

2番目は要するに普通のメソッドなのですが、「インスタンスメソッド」と呼ばれたりします。

※ ところで、IOやObjectといった、Rubyのクラスも「クラスオブジェクト」というオブジェクトの一種だったりします。その意味では、1番目と2番目は実は同じもので、違いは「レシーバがあるかないか」の2種類しかないのですが、定義の仕方の違い等わかりやすさのため、ここでは分けて紹介しています。

3番目については、実際にはレシーバは省略されているだけで、暗黙のレシーバとしてselfに対するメソッドになります。
関数のような形なので、「関数形式」「関数的メソッド」と呼ばれることもあります。
https://docs.ruby-lang.org/ja/2.5.0/doc/spec=2fcall.html

ZizyNonnoさんの書かれたhelloメソッドはこの3番目の関数形式を使うものですね。「ピカチュウの10まんボルト」とは違う形に見えますが、ピカチュウが省略されていて見えないだけで、実際にはピカチュウ役のオブジェクトはいるのです。

メソッドの定義について

その上で、メソッド定義の話をします。

find_byメソッドは、maisumakunさんの回答で書かれている通り、Railsが提供しているメソッドで、ActiveRecord::FinderMethodsモジュールのメソッドとして定義されています。
User.find_by(id: params[:id])というのは、Userクラスのクラスメソッドですね。UserクラスはApplicationRecordのサブクラスで、ApplicationRecordは最終的にActiveRecord::FinderMethodsモジュールをincludeしている、という関係になっているはずです。
単純にUserクラスにfind_byメソッドが定義されているわけじゃないのでちょっと分かりづらいですね……。

一方、helloメソッドは、外側がクラスやモジュールで囲われていません。こういうのは「トップレベル」と言われていて、helloメソッドのような場合はトップレベルのメソッドなどと呼ばれます。
トップレベルで定義されたメソッドは、Objectクラスのprivateなインスタンスメソッドになります。
https://docs.ruby-lang.org/ja/latest/class/main.html

※ privateメソッドは、関数形式でしか呼び出せない(つまりレシーバを書けない)メソッドのことです。


メソッドはいろんな定義の仕方と使われ方があって、いきなりおぼえようとすると混乱しがちになるかもですが、少しずつ使っているうちに慣れてくるかと思います。

自分でもいろいろ定義したり呼び出したりしてみて、試してみると理解が進むと思います。

投稿2018/07/27 08:27

takahashim

総合スコア1877

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

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

0

メソッドは本来オブジェクトに働きかけるものなのですが、クラスも何もなしでメソッドを作れる、というのはRubyの特殊なところです(もっとも、大きなプログラムを作る上では、クラスもなにもない「外側」に書くコードは最低限のものだけになるので、自分でメソッドを作るような場面はそう訪れません)。

なお、user.find_byのメソッドはRailsが用意しています。このメソッドの場合、ソースコード上できちんとdef find_byとなっていますが、Railsにはプログラムを実行して動的にメソッドを作成する、「メタプログラミング」という技法が多用されていますので、メソッド定義が見つからないこともあります。

投稿2018/07/27 06:50

maisumakun

総合スコア145121

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

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

zyno

2018/07/27 07:22

ご回答ありがとうございます! maisumakunさんの文章の雰囲気から、クラスの内側に書くメソッドはクラスメソッドであると推察したのですが合っていますでしょうか? そして、クラスメソッドと```user.find_by```のようなメソッドの違いが判らなくなりました。クラスメソッドはRailsでいうmodelのような場所で多く使われているイメージで、それ以外で使えないといったイメージがあります。対して```user.find_by```のようなメソッドだとfind_byメソッドは例が悪いですが、広義の意味でとらえると、mvcいずれでも使えるイメージがあります。2つの違いについてご教授願えればと思います。
maisumakun

2018/07/27 08:11

いえ、厳密に言えばRubyに「クラスメソッド」という種類のメソッドはありません。すべてのメソッドはインスタンスメソッドです。 ただし、Rubyの場合、クラス自体がClassクラスのオブジェクトであること、そして各オブジェクトに「特異クラス」という、「そのオブジェクトだけに適用されるクラス」があるので、クラスオブジェクトの特異クラスにメソッドを入れることで、他言語でいう「クラスメソッド」のように運用できます。 後半の「イメージ」は、ZizyNonnoさんの勝手な思い込みです。すっかり忘れてください(どんなメソッドをどのような場所で使っても構いません)。
maisumakun

2018/07/27 08:15 編集

ふつうに「def 名前」のように定義するメソッドは、インスタンスメソッドです。 「クラスメソッド」を定義する場合、「特異メソッドとして定義する 『def object.名前』の書式を使う」あるいは「class << selfで特異クラスを開いて、その中で定義する」というような手順となります。
guest

0

最初から使えるなら Rails なり C++なりRubyなりが持っているものです。

で、メソッドっていうのは本来は 「クラスが持つ関数」のことだと思います。

メソッド -> method. 方法, 手法。

クラスは 処理 ( メソッド ) と データ ( フィールド ) から成ります。

なのでメソッドと名前がつけられているだけ。

C言語でいう関数を、クラスが保持しているやつって感じ。

で、質問にあるのは、質問者さんのご考え通り、#1 がメソッドで #2 が関数です。

maisumakunさんの言葉をお借りすると、

メソッドは本来オブジェクトに働きかけるもの

ですね。まさにこれ。

オブジェクトが持つデータに変更を加えたりするものです。

投稿2018/07/27 07:33

編集2018/07/27 07:34
BeatStar

総合スコア4958

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

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

maisumakun

2018/07/27 08:06

トップレベルで作ったメソッドも、mainと仮に呼ばれるオブジェクトのメソッドとして扱われます(もっとも、privateメソッドなので、mainオブジェクトからは呼べませんが)。 https://docs.ruby-lang.org/ja/latest/class/main.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問