1
0

More than 1 year has passed since last update.

[Ruby]インスタンス生成していないクラスが実行?

Last updated at Posted at 2022-02-16

Ruby環境設定後、スクリプトファイルを試験動作させて素朴な疑問がわいたので記録しておく。
内容がほぼ個人的備忘録であり、疑問レベルも恐らく初歩も良いところと思う。
しかし、同じ疑問で躓く人が他に居るかもしれず、何かの役に立てれば幸いだと思う。

疑問に思ったこと

インスタンス生成していないクラスが、なぜ実行されているのか?

用意した環境

  • Windows 10 Pro / 21H2
  • RubyInstaller 3.1.0-1 released

用意したファイル

標準出力へ文字列を出力クラスを定義しただけのスクリプトファイル。
メソッドもなし。

test1.rb
class Foo
    p "PUT TEST"
end

想定していた実行結果

「p "PUT TEST"」は、クラス「Foo」内にメソッドも実装せず記述しただけなので、
Rubyインタプリタから実行しても、標準出力に"PUT TEST"は出てこないはずと思っていた。

……正直言うと上のスクリプト「test1.rb」は、単にメソッドを記述忘れで出来たミス産物なので、
本当は「p "PUT TEST"」はメソッドへ実装する予定だった。
「それなら想定もクソもないし最初からそう書け」と思われるかもしれないが、
備忘録として話がややこしくなるので、ここは暫し目をつぶって貰いたい。

実際の実行結果

上記スクリプトファイルをRubyインタプリタで起動。
下記のように、"PUT TEST"が出力された。

コマンドプロンプト
> ruby test1.rb
"PUT TEST"

他に試したこと

スクリプト、クラス定義、初期化メソッド、独自メソッド、
インスタンス生成、メソッド呼び出しのタイミングでそれぞれ、デバッグ文字列を出力するようにしてみた。

test2.rb
p "test:outer:1"

class Foo
    p "test:inner:1"
    def initialize()
        p "test:initialize"
    end
    p "test:inner:2"
    def test1()
        p "test:test1"
    end
    p "test:inner:3"
end

p "test:outer:2"
tObj=Foo.new
p "test:outer:3"
tObj.test1
p "test:outer:4"
コマンドプロンプト
>ruby test2.rb
"test:outer:1"
"test:inner:1"
"test:inner:2"
"test:inner:3"
"test:outer:2"
"test:initialize"
"test:outer:3"
"test:test1"
"test:outer:4"

試した結果わかったこと

最初の出力が、スクリプト先頭の"test:outer:1"
次の出力がクラス「Foo」すぐ内側へ記述した"test:inner:1"が出力ということは、
クラスのすぐ内側へ記述したものは、その定義クラスが読み込まれた時点で実行されているようである。

文献

ここまで調べた後にRubyのリファレンスマニュアルを良く見たら、「クラス定義」の説明中に、下記の記載があるのを見付けた。

クラス定義式中には任意の式を書くことができクラス定義の際に実行されます。

他に参考とした外部URL

Rubyでクラス宣言直下に書かれたメソッドの実行時期
https://yucatio.hatenablog.com/entry/2016/06/30/224138

Rubyのクラス定義直下のメソッドの実行タイミングについて
https://dev.classmethod.jp/articles/ruby-under-class-method-timing/

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0