使用散列长度作为迭代器多次调用其他方法的方法

我有两种方法可以多次调用。 我想要调用它们的次数取决于我正在使用的哈希计数。 我正在尝试创建一个调用其他2的新方法,并重复哈希计数的长度。 我的问题是我收到了错误

"findfiles2.rb:61:in` `chdir': no implicit conversion of Enumerator into String (TypeError) from findfiles2.rb:61:in `store_directories' from findfiles2.rb:138:in `block in repeat' from findfiles2.rb:134:in `loop' from findfiles2.rb:134:in `repeat' from findfiles2.rb:153:in `'" 

这是我的代码:

 require 'date' require "mail" options = { :address => "smtp.gmail.com", :port => 587, :domain => 'gmail.com', :user_name => 'username', :password => 'password/', :authentication => 'plain', :enable_starttls_auto => true } mail_sender = "somename@gmail.com" mail_recipient = "somename@yahoo.com" directories = { "directory1" => "/path/to/folder1/", "directory2" => "/path/to/folder2/", "directory3" => "/path/to/folder3/", "directory4" => "/path/to/folder4/", "directory5" => "/path/to/folder5/" } directory_count = directories.count.to_i file_output = "/path/to/output/" exclude_folder = 'sample' output_file_name = "directory_list" output_file_extension = ".csv" date_today = Date.today.to_s log_file_path = "/path/to/output/" log_name = "script_log_" + date_today + ".txt" log_file_name = log_file_path + log_name # starts log file def start_log(file_output, log_name) Dir.chdir(file_output) log_output = File.open(log_name, 'a+') $stdout = log_output puts Time.now.to_s + " > " + "Starting Script..." puts "_______________________________________________" end # stores subdirectory contents into an array def store_directories(directory, folder_to_exclude) # changes working directory to the directory variable puts Time.now.to_s + " > " + "Updating search directory..." Dir.chdir(directory) # outputs only subdirectories with a creation date of older than 24 hours, except for folders names 'test' Dir.glob("*.*").map(&File.method(:realpath)) puts Time.now.to_s + " > " + "Gathering subdirectories..." subdir_list=Dir.glob("*").map(&File.method(:realpath)).reject{|files| (not File.directory?(files) && (File.mtime(files)  " + "Saving contents to: " + file_name File.open(file_name, "a+") do |f| directory_list.each { |element| f.puts(element) } end else puts Time.now.to_s + " > " + "This directory does not contain any subdirectories that are older than 24 hours" exit end end # sends an email containing today's report if a file was created today def send_email(today_date, output_file_path, output_file_name, output_file_extension, mail_options, email_sender, email_recipient) backlog_file = output_file_path + output_file_name + "_" + today_date + output_file_extension if File.exist?(backlog_file) == true puts Time.now.to_s + " > " + "Sending email report to: " + email_recipient + "..." Mail.defaults do delivery_method :smtp, mail_options end Mail.deliver do to email_recipient from email_sender subject 'Backlog for ' + today_date body 'Attached is a report showing any batches that have not been processed within the last 24 hours.' add_file backlog_file end else puts Time.now.to_s + " > " + "No batches older than 24 hours to report" exit end end 

这是给我带来麻烦的方法

 def repeat(directory, times, exclude_folder) # fail "times must be 1 or more" if times < 1 counter = 1 # counter_string = counter.to_s # puts counter_string # directory_counter = directory + counter_string loop do if counter != times subdir_list_contents = store_directories(directory, exclude_folder) directory_check(subdir_list_contents, file_output, date_today, output_file_name, output_file_extension) counter = counter + 1 else break end end end 

这是我开始运行一切的地方。

 # Starting log file... start_log(file_output, log_name) repeat(directories.each, directory_count, exclude_folder) # # outputs contents of directory 1 to the file (I want to perform this for the amount of times equal to the hash length, which is what I'm creating the repeat method for) subdir_list_contents = store_directories(directory1, exclude_folder) directory_check(subdir_list_contents, file_output, date_today, output_file_name, output_file_extension) # # # If there is a new file from today, sends an email with file as attachment send_email(date_today, file_output, output_file_name, output_file_extension, options, mail_sender, mail_recipient) 

你的代码太长了。 如你所见,没有人会帮助你。

 $ ruby -w t.rb t.rb:125: warning: mismatched indentations at 'end' with 'def' at 104 t.rb:37: warning: assigned but unused variable - log_file_name /Users/b/.rvm/rubies/ruby-2.4.0-rc1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55: in `require': cannot load such file -- mail (LoadError) 

发布我们可以运行的代码。 我不打算安装整个邮件服务器。 所以我评论出来

 #require "mail" 

然后

 t.rb:44:in `chdir': No such file or directory @ dir_chdir - /path/to/output/ (Errno::ENOENT) 

等等

请按照错误消息:

 t.rb:62:in `chdir': no implicit conversion of Enumerator into String (TypeError) from t.rb:62:in `store_directories' from t.rb:139:in `block in repeat' from t.rb:136:in `loop' from t.rb:136:in `repeat' from t.rb:149:in `
'

您需要跟踪的所有内容都是repeatstore_directories ,因此您可以将已发布的代码减少到此严格的最小值以重现错误:

 directories = { "directory1" => "/path/to/folder1/", "directory2" => "/path/to/folder2/", } directory_count = directories.count.to_i exclude_folder = 'sample' # stores subdirectory contents into an array def store_directories(directory, folder_to_exclude) puts "directory=#{directory.inspect} folder_to_exclude=#{folder_to_exclude}" Dir.chdir(directory) end def repeat(directory, times, exclude_folder) store_directories(directory, exclude_folder) end repeat(directories.each, directory_count, exclude_folder) 

执行:

 $ ruby -w t.rb directory=#"/path/to/folder1/", "directory2"=>"/path/to/folder2/"}:each> folder_to_exclude=sample t.rb:12:in `chdir': no implicit conversion of Enumerator into String (TypeError) from t.rb:12:in `store_directories' from t.rb:16:in `repeat' from t.rb:19:in `
'

如果你这样做了,你甚至不必发一个问题,因为错误的原因是显而易见的。 在

 repeat(directories.each, directory_count, exclude_folder) 

directories.each返回一个Enumerator。 删除each

 $ ruby -w t.rb directory={"directory1"=>"/path/to/folder1/", "directory2"=>"/path/to/folder2/"} folder_to_exclude=sample t.rb:12:in `chdir': no implicit conversion of Hash into String (TypeError) from t.rb:12:in `store_directories' from t.rb:16:in `repeat' from t.rb:20:in `
'

我想你想要做的是为每个目录调用一次:

 def repeat(directory, exclude_folder) puts "in repeat directory=#{directory} exclude_folder=#{exclude_folder}" store_directories(directory, exclude_folder) end directories.each { | _key, directory | repeat(directory, exclude_folder) } 

执行:

 $ ruby -w t.rb in repeat directory=dir1 exclude_folder=sample in store_directories directory="dir1" folder_to_exclude=sample in repeat directory=dir2 exclude_folder=sample in store_directories directory="dir2" folder_to_exclude=sample t.rb:18:in `chdir': No such file or directory @ dir_chdir - dir2 (Errno::ENOENT) from t.rb:18:in `store_directories' from t.rb:53:in `repeat' 

chdir有副作用:它更改当前目录,下次,它将开始在新的当前目录中搜索。 要避免这种情况,您需要恢复以前的状态:

 def store_directories(directory, folder_to_exclude) puts "in store_directories directory=#{directory.inspect} folder_to_exclude=#{folder_to_exclude}" current_directory = Dir.getwd Dir.chdir(directory) # ... # Restore the directory that was current when entering the method. # Without it, the next chdir will start from the directory left by the previous chdir. Dir.chdir(current_directory) end 

现在它有效:

 $ ruby -w t.rb in repeat directory=dir1 exclude_folder=sample in store_directories directory="dir1" folder_to_exclude=sample in repeat directory=dir2 exclude_folder=sample in store_directories directory="dir2" folder_to_exclude=sample 

经过几次更改后,我最终得到了这个:

 require 'date' directories = { "directory1" => 'dir1', "directory2" => 'dir2' } exclude_folder = 'sample' @file_output = '.' @date_today = Date.today.to_s @output_file_name = 'directory_list' @output_file_extension = '.csv' # stores subdirectory contents into an array def store_directories(directory, folder_to_exclude) puts "in store_directories directory=#{directory.inspect} folder_to_exclude=#{folder_to_exclude}" current_directory = Dir.getwd puts Time.now.to_s + " > " + "Updating search directory..." # changes working directory to the directory variable Dir.chdir(directory) # outputs only subdirectories with a creation date of older than 24 hours, except for folders names 'test' puts Time.now.to_s + " > " + "Gathering subdirectories..." subdir_list = Dir.glob("*").map { | file | File.realpath(file) } puts "all files : subdir_list=#{subdir_list}" puts "directory + folder_to_exclude=#{directory + folder_to_exclude}" # nonsense subdir_list = subdir_list.reject do | file | not File.directory?(file) \ && File.mtime(file) < Time.now - 86400 \ && (not file == folder_to_exclude) end puts "after reject : subdir_list=#{subdir_list}" # Restore the directory that was current when entering the method. # Without it, the next chdir will start from the directory left by the previous chdir. Dir.chdir(current_directory) puts "subdir_list=#{subdir_list.inspect}" subdir_list end # checks to see if there are any directories in the array def directory_check(directory_list, save_to_file, today_date, output_file, output_extension) if directory_list.empty? == false # changes the working directory to the file output directory for the file Dir.chdir(save_to_file) # <----------------- problem !!!! # writes the array contents into a new file file_name = output_file + "_" + today_date + output_extension puts Time.now.to_s + " > " + "Saving contents to: " + file_name File.open(file_name, "a+") do |f| directory_list.each { |element| f.puts(element) } end else puts Time.now.to_s + " > " + "This directory does not contain any subdirectories that are older than 24 hours" end end def repeat(directory, exclude_folder) puts "in repeat directory=#{directory} exclude_folder=#{exclude_folder}" subdir_list_contents = store_directories(directory, exclude_folder) directory_check(subdir_list_contents, @file_output, @date_today, @output_file_name, @output_file_extension) end directories.each { | _key, directory | repeat(directory, exclude_folder) } 

执行:

 $ ruby -w t.rb in repeat directory=dir1 exclude_folder=sample in store_directories directory="dir1" folder_to_exclude=sample 2017-10-27 08:05:24 +0200 > Updating search directory... 2017-10-27 08:05:24 +0200 > Gathering subdirectories... all files : subdir_list=["/userdata/devl/ruby/zintlist/directories/dir1/x1.txt", "/userdata/devl/ruby/zintlist/directories/dir1/x2.txt"] directory + folder_to_exclude=dir1sample after reject : subdir_list=[] subdir_list=[] 2017-10-27 08:05:24 +0200 > This directory does not contain any subdirectories that are older than 24 hours in repeat directory=dir2 exclude_folder=sample in store_directories directory="dir2" folder_to_exclude=sample 2017-10-27 08:05:24 +0200 > Updating search directory... 2017-10-27 08:05:24 +0200 > Gathering subdirectories... all files : subdir_list=["/userdata/devl/ruby/zintlist/directories/dir2/x3.txt"] directory + folder_to_exclude=dir2sample after reject : subdir_list=[] subdir_list=[] 2017-10-27 08:05:24 +0200 > This directory does not contain any subdirectories that are older than 24 hours