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

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

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

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

Q&A

解決済

2回答

421閲覧

<Ruby>クラス宣言内、及びメソッドの宣言外からのメソッド呼び出しの利用について

NK321

総合スコア1

Ruby

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

0グッド

1クリップ

投稿2022/09/26 17:11

前提

例えばJavaではタイトルのような、"クラス内、かつメソッド宣言外"から直接メソッドを呼ぶような式はエラーになるかと思います。
<例1>

Java

1public class Main { 2 public static void main(String[] args) { 3 System.out.println("Hello world!"); 4 } 5 public static void log(String message) { 6 System.out.println(message); 7 } 8 // エラーになる 9 log("call from in class, and from outside method declaration"); 10}

しかし、Rubyではこのようなことが可能かと思います。

Ruby

1class SampleController < ActionController::Base 2 def log(message) 3 puts message 4 end 5 # エラーにならない 6 log("call from in class, and from outside method declaration") 7end

確認したいこと

以下ご教授いただければと思います

  1. Rubyの場合、親クラスで上記のような処理が書かれていた場合、継承された時に処理が実行される為、必ず処理させたい内容を記載し継承させる、という用途で良いのでしょうか?
  2. この書き方は何か名称があったりしますでしょうか?

以上、よろしくお願いいたします。

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

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

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

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

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

NK321

2022/10/01 13:28

お二方とも参考になりました、ありがとうございました。 迷いましたがサンプルコードを記載して、よりわかりやすかった方をBAとさせていただきました。
guest

回答2

0

ベストアンサー

Ruby の場合、クラス定義の中に書くのは任意の式で、書いたように実行されます。特にそれについての名称は無いと思います。
リファレンスマニュアルより:

クラス定義式の中は self がそのクラスであることと、 呼び出し制限のデフォルトが異なること以外にトップレベルとの違いはありません。クラス定義式中には任意の式を書くことができクラス定義の際に実行されます。

無理矢理な例ですが、こういうのも文法的にはOKです。メソッド定義も値(メソッド名のシンボル)を返す式です。

Ruby

1class Foo 2 x = [ 3 def a; end, 4 def b; end 5 ] 6 x.each { |w| private w } 7 p self.private_instance_methods - Class.private_instance_methods 8end

また、

親クラスで上記のような処理が書かれていた場合、継承された時に処理が実行される為、

SampleControllerを継承したクラスを定義するとその子クラスに何も書かなくてもlog(~~)が子クラス定義時点で実行されると言う意味なら勘違いでしょう。書いてない物は実行されません。あるいは違う意味でしょうか?

投稿2022/09/27 01:10

otn

総合スコア84423

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

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

NK321

2022/09/27 03:49

ご回答いただき、ありがとうございます。 リファレンスに記載があったようで、読み込みが足りませんでした。 また、サンプルコードまで提示いただきまして、重ねてお礼申し上げます。 継承した際の動作についてですが、記載が曖昧で申し訳ありません。 例えばもっとシンプルにして、putsをするだけのクラスを継承した場合にputsが実行される、という意味合いとなります。 これは実行されるようなので、実際の使い方としては、継承したクラスに実行させたい処理の呼び出しを記載しておく使い方をするのかな・・・?と感じています。 ``` class SampleController < ActionController::Base puts("Hello, from parent class") end ```
otn

2022/09/27 04:08

> これは実行されるようなので、 それは勘違いか記憶違いですね。実行されません。 > 継承したクラスに実行させたい処理の呼び出しを記載しておく使い方をするのかな 記載すればもちろん記載したコードは実行されます。
otn

2022/10/01 13:45 編集

実際に実行してみれば、親クラス定義時にのみ実行され、継承時(子クラス定義時)には実行されてないことがわかると思います。 勘違いですね。
NK321

2022/10/01 15:51

なるほど!言われてみればそうですね。 また、ドキュメントを見た所、継承をトリガーとするのであれば[inherited]というメソッドがありましたので、継承された時に発火させたい処理はここに定義すればよさそうですね。 https://docs.ruby-lang.org/ja/latest/method/Class/i/inherited.html
guest

0

Rubyではこのようなことが可能かと思います。

いえ、クラス直下ではselfがクラスオブジェクトですので、実行できるのはクラスメソッドです。インスタンスメソッドは呼べません。

投稿2022/09/26 22:19

maisumakun

総合スコア145121

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

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

maisumakun

2022/09/26 22:48

なお、attr_readerやvalidatesのような、クラス直下に書くことを前提としたメソッドは、「クラスマクロ」と呼ばれることもあります。
NK321

2022/09/27 03:58

ご回答いただき、ありがとうございます。 おっしゃる通りで、私のサンプルコードが正しくなかったです。 もっとシンプルに、putsをするだけのクラスを継承した場合に、継承時にputsされる。というニュアンスでした。 ``` class SampleController < ActionController::Base puts("Hello, from parent class") end ``` クラスメソッドを定義して、そのメソッドを"クラス直下から呼び出す"という事は可能のようで、この辺りはJavaなどと異なるようですね。 クラス直下で呼び出されるメソッドは「クラスマクロ」と呼ばれることもあるとのことで、承知しました。 (また、本題とはそれますが、ブラウザでRubyが実行できる環境があるのですね、参考にさせていただきます。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問