Railsのスコープ定義文を見ていたら、クラス宣言直下に書かれたメソッドはいつ実行されるのかという疑問がわいてきたので調べました。
Rubyはクラス宣言直下に任意の式が書ける
railsのコードでは、クラス宣言直下でscopeメソッドを呼び出しています。
class Book < ActiveRecord::Base
scope :costly, -> { where("price > ?", 3000) }
end
"初めてのRuby (Yugui 著)"には、
クラス定義の内には任意の式を書くことができます
と書いてあります。
クラス宣言直下に書かれたメソッドはいつ実行されるのか
クラス定義直下に書かれたメソッドがいつ実行されるのか、コードを書いて確かめます。
class CallUnderClassDefTest
puts "from under class def 01"
def method_01
puts "from method_01"
end
puts "from under class def 02"
end
puts "out of class 01"
CallUnderClassDefTest.new.method_01
puts "out of class 02"
実行結果
from undfer class def 01
from under class def 02
out of class 01
from method_01
out of class 02
ファイルの先頭から処理が実行されているようです。
クラスの宣言が終わっていないのにメソッドが実行できるというのは不思議ですが、これもスクリプト言語の特徴なのでしょう。
Javaのstaticブロック
Javaはコンパイル言語なので同様の機能は無いのですが、staticブロック内には任意の式を書くことができます。使用用途としては、クラス変数の初期化などです。以下のコードで実行順序を確認してみます。
public class SomeClass {
private static List<String> fruitList = new ArrayList<String>();
static {
System.out.println("||static block start||");
fruitList.add("apple");
fruitList.add("banana");
fruitList.add("coconut");
System.out.println("||static block end||");
}
public static List<String> getFruitList() {
return fruitList;
}
}
public class StaticBlockTest {
public static void main(String[] args) {
System.out.println("start main");
List<String> fruits = SomeClass.getFruitList();
System.out.println("==== fruits ====");
for (String fruit : fruits) {
System.out.println(fruit);
}
System.out.println("================");
System.out.println("end main");
}
}
実行結果
start main
||static block start||
||static block end||
==== fruits ====
apple
banana
coconut
================
end main
mainメソッドが呼ばれたあとにSomeClassのstaticブロックが実行されています。
Rubyを習い始めた時は、Rubyのクラス宣言直下に書かれた処理は、Javaのようにクラスが呼び出された際に実行されると思っていたので、今回確かめることができ、勉強になりました。