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言語のトークン連結子##みたいなもんか