動的ディスパッチ
メソッド実行時にメソッドを動的に呼び出す。
日づけごとに天気を返すメソッドがあって、それを動的ディスパッチでメソッドを呼んでみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| class Weather
def weather_of_day(day)
send("weather_of_day_#{day}")
end
def weather_of_day_1
"快晴"
end
def weather_of_day_2
"多分雪"
end
def weather_of_day_3
"ほどよく寒い曇り空"
end
def weather_of_day_4
"寒いよ。雨"
end
def weather_of_day_5
"晴れ時々曇り"
end
def method_missing(method_id,*args)
return "#{$1}日は指定できません" if method_id =~ /^weather_of_day_(.*)/
super
end
end
Weather.new.weather_of_day(1) #=> "快晴"
Weather.new.weather_of_day(3) #=> "ほどよく寒い曇り空"
|
動的メソッド
動的にメソッドを作成する
instance variable getでインスタンス変数の値は簡単にとれますが、それがない体で。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| class Me
def initialize
@first_name = "gogo"
@last_name = "sakura"
end
def self.generate_name_accessor(prefix)
prefix = prefix.to_s
define_method "#{prefix}_name" do
prefix != "full" ? instance_eval("@#{prefix}_name") : [@first_name,@last_name].join("_")
end
end
generate_name_accessor :full
generate_name_accessor :first
generate_name_accessor :last
end
Me.new.first_name #=> "gogo"
Me.new.last_name #=> "saura"
Me.new.full_name #=> "gogo_sakura"
|
まとめ
メソッド名に一定のルールがあり、それを引数等に応じてメソッド名を決定し動的に呼ぶ場合
→動的ディスパッチ
重複している箇所がある場合にメソッドの内容が似通っているなら
→動的メソッド
辺りを使い分けてリファクタリングすると幸せになれるかも?