# メソッドの動的呼び出し

```require "colored"
puts "this is red".red
```

とかやるとターミナルに赤く表示される。が、色々色があるときにcaseで分けてやるとか面倒なので、"red"とかのmethodを呼び出すのを動的にしたい。結論からいうとKernel#sendを使うとうまく扱うことができる(すぐに忘れる)。

```% cat data/WordLevel_10.txt
Document-Level Polarity: 0.512755, 0.487245
0.833333, 0, 0.166667: ,(0.5, 0, 0.5) sorry(1, 0, 0) bill(1, 0, 0)
0.423077, 0.461538, 0.115385: this(0.5, 0.5, 0) and(0.5, 0, 0.5) have(0.5, 0.5, 0) a(0, 0.5, 0.5) only(1, 0, 0) made(0, 1, 0) most(0.5, 0.5, 0) purchase(0, 0.5, 0.5) poor(0.5, 0.5, 0) fair(0.5, 0.5, 0) production(0.5, 0.5, 0) disappointing(0, 1, 0) lyrics(1, 0, 0)
0.346154, 0.423077, 0.230769: this(0.5, 0.5, 0) to(0, 0.5, 0.5) the(0, 1, 0) is(0.5, 0.5, 0) ,(0.5, 0.5, 0) but(0.5, 0, 0.5) enough(0.5, 0, 0.5) material(0, 0.5, 0.5) save(0, 1, 0) adequate(0, 0.5, 0.5) playing(1, 0, 0) guitar(0.5, 0.5, 0) not_good(0.5, 0, 0.5)
0.111111, 0.666667, 0.222222: the(0, 0.5, 0.5) i(0, 1, 0) a(0, 0.5, 0.5) thought(0.5, 0.5, 0) on(0, 0, 1) more(0.5, 0.5, 0) out(0, 1, 0) little(0, 0, 1) time(0, 1, 0) before(0, 1, 0) material(0, 1, 0) his(0, 1, 0) bill(0.5, 0, 0.5) next(0, 1, 0) hope(0, 1, 0) process(0, 1, 0) bringing(0.5, 0, 0.5) spends(0, 1, 0)
```

で、こんなスクリプトをでっちあげる。

```require "colored"

# RubyにはRでいうところのwhich.minみたいな関数はないんでしたっけ...?
class Array
def max_index
max_index = 0
max = - 1.0/0
self.each_with_index{|elem, index|
if elem > max
max = elem
max_index = index
end
}
return max_index
end
end

polarity2color = Hash.new
polarity2color[0] = "blue"
polarity2color[1] = "red"
polarity2color[2] = "green"

if ARGV.size != 1
puts "usage; ruby #{__FILE__} filename"
exit
end

filename = ARGV[0]

if !File.exist?(filename)
STDERR.puts "#{filename} doesn't exist!"
exit
end

File.open(filename, "r") {|file|
skip_num = file.gets.split("\s").last.to_i
skip_num.times do
file.gets
end
file.each{|line|
line.chomp!
if line =~ /(\d*.\d*), (\d*.\d+), (\d*.\d+): (.*)/
sentence_pos_prob = \$1; sentence_neg_prob = \$2; sentence_neu_prob = \$3; rest = \$4
sentence_pos_prob = sentence_pos_prob.to_f; sentence_neg_prob = sentence_neg_prob.to_f; sentence_neu_prob = sentence_neu_prob.to_f
sentence_prob = [sentence_pos_prob, sentence_neg_prob, sentence_neu_prob]
max_index = sentence_prob.max_index
print "#{sentence_prob[max_index].to_s.send(polarity2color[max_index]).send(:underline)} "
rest.scan(/(.*?)\((\d*.\d*), (\d*.\d*), (\d*.\d*)\) /).each{|chunk|
word, word_pos_prob, word_neg_prob, word_neu_prob = chunk
word_pos_prob = word_pos_prob.to_f; word_neg_prob = word_neg_prob.to_f; word_neu_prob = word_neu_prob.to_f
word_prob = [word_pos_prob, word_neg_prob, word_neu_prob]
print "#{word.send(polarity2color[word_prob.max_index])} "
}
puts
end
}
}
```

すると、こんな感じの出力を得ることができる。ターミナルの上で見れるので(自分にとって)便利。

sendとかの分かりやすい例はRubyベストプラクティス -プロフェッショナルによるコードとテクニックのp75とかに載っていた。