renamemodule.rb
むしゃくしゃして作った。モジュール名変えられるならなんでもよかった。今は公開している。
実行すると、変更するモジュール名を聞いてきて、カレントディレクトリ以下の*.ml{i,l,y,}ファイルの中のモジュール名を変更します。変更点は、対話的に表示され、確認できます。すべて変更する場合はEnterをずーっと押してれば大丈夫です。(変更の最後の確認は、yかnを入れないと行われません。)
sedでいいような気もしてきた。
require 'pathname' require 'fileutils' class Pathname def each_children(ptn=/.*/, exc=nil, &blk) children.each { |path| if exc && exc !~ path.basename.to_s if path.directory? path.each_children(ptn,exc,&blk) else if ptn =~ path.to_s yield(path) end end end } end end def gets_or_exit() x = gets() if x then x.chomp() else exit 0 end end def yes_no(prompt, yes, no) print prompt x = gets_or_exit if yes.include?(x) true elsif no.include?(x) false else yes_no(prompt, yes, no) end end def rename_src(old,new,path) old_ptn = /\b#{old}\b/ renamed = false lines2 = [] lines = path.readlines lines.each { |l| if l =~ old_ptn puts "#{path.to_s}:" puts " #{l.chomp.strip}" puts " =>" puts " #{l.chomp.strip.gsub(old_ptn, new)}" if yes_no("Replace?(Y/n) :", ["y","Y",""], ["n","N"]) renamed = true l.gsub!(old_ptn, new) end end } if renamed lines else nil end end def rename_file(old,new,path) if path.basename.to_s =~ /^#{old}\.ml(l|y|i)?$/ newname = "#{path.dirname}/#{new}.ml#{$1}" path.rename(newname) end end def module_name(f) f[0].chr.upcase + f[1,f.length-1] end while true print "Old file name: " old = gets_or_exit() print "New file name: " new = gets_or_exit() break if yes_no("#{old}(#{module_name(old)}) => #{new}(#{module_name(new)}), OK?(Y/n): ", ["y","Y", ""], ["n","N"]) end renamed = {} Pathname.new(".").each_children(/\.ml(l|y|i)?$/, /\.svn/) {|path| content = rename_src(module_name(old), module_name(new), path) if content renamed[path] = content end } puts "Following files will be updated: " renamed.keys.each {|path| puts " " + path.to_s } if yes_no("OK?(y/n)", ["y","Y"], ["n", "N"]) renamed.each {|path,lines| FileUtils.cp(path.to_s, path.to_s + "~~") path.open("w") {|f| lines.each {|l| f.puts l } } } end
ちなみに、これ作ってるときに型チェッカが欲しいと思ったのは、
- Hash#keysかhash#keyか迷った
- Array#include?かArray#includeか迷った
- Hash.eachの引数が、keyのみかvalueも含むのか迷った
- パラメータ数を変えたら再帰呼び出しを修正するの忘れた
くらいか。
大きくなると、これがうざくなってくるハズ。
※ちょっと修正