Here is my basic script to rename a file tree of files starting at the given directory:
require 'fileutils'
module Renamer
class Application
def initialize
@directory = Dir.pwd
end
def rename(dir, extension, change_to)
Dir.glob("#{dir}").each do |f|
next if %w(. ..).include? f
if File.directory? f
rename f, extension, change_to
else
puts "Renaming file: #{f}"
FileUtils.mv f, "#{File.dirname(f)}/#{File.basename(f, '.*')}.#{change_to}" if File.extname f == ".#{extension}"
end
end
end
def start
puts 'What file extension do you want to change?'
extension = gets.chomp
puts 'What do you want to change it to?'
change_to = gets.chomp
rename @directory, extension, change_to
puts 'Renaming completed!'
end
end
app = Application.new
app.start
end
For some reason it throws a SystemStackError at line 11, which is bizarre to me. If at the Dir.glob method I simply place a concatenation for the extension alongside the dir variable and delete the "if" modifier on the statement that actually renames the files, all of the files in the current directory are renamed but not anywhere else since I'm not digging into the other directories, and also tells me that the code is functional. How can this error be resolved?
A simple p f
at the start of the block reveals the problem. Dir.glob
expands file globs, but you're only passing Dir.pwd
(with no glob). So your cwd is passed to rename, it is certainly a directory so it immediately passes itself to rename again, cue endless recursion and a stack error.
If you change it to Dir.glob("#{dir}" + "/*")
then you're actually globbing something!
After doing so you'll also find that you need to add more parentheses on line 18 because the parser is getting confused.
On a different note, I recommend the find library. It is specifically designed for recursively iterating through a directory.