evalって便利ですね
RubyのIRCライブラリを見ていると、サーバからのリプライを受けるメッセージのクラスを定義するのに、以下のような記述がなされていました。
def self.regist_command cmd eval <<E class #{cmd} < Command end Commands['#{cmd}'] = #{cmd} def #{cmd.downcase}(*params) #{cmd}.new(nil, '#{cmd}', params) end module_function :#{cmd.downcase} E end Commands = {} %w(PASS NICK USER OPER MODE SERVICE QUIT SQUIT JOIN PART TOPIC NAMES LIST INVITE KICK PRIVMSG NOTICE MOTD LUSERS VERSION STATS LINKS TIME CONNECT TRACE ADMIN INFO SERVLIST SQUERY WHO WHOIS WHOWAS KILL PING PONG ERROR AWAY REHASH DIE RESTART SUMMON USERS WALLOPS USERHOST ISON ).each do |cmd| self.regist_command cmd end
同様のクラスを大量に作る場合は一々羅列せずにevalを使えばいいのかー、とちょっと感動した今日でした。それだけ。
♯C言語のトークン連結子##みたいなもんか