循环遍历ruby rake中新创建的数组

时间:2018-01-08 21:29:10

标签: arrays ruby loops rake

我还有一个关于Ruby的问题。 我想做的是:

  1. 使用grep
  2. 从文件创建子文件
  3. 创建一个名为ARRAY
  4. 的新空数组
  5. 将子文件的每一行作为ARRAY
  6. 中的元素推送
  7. 循环遍历ARRAY的每个元素,并为每个元素创建一个文件(#{element} .txt)。
  8. 到目前为止我所拥有的:

    desc "Create subfile"
    file "subfile.txt" => ["infile.txt"] do
    sh "grep '>' infile.txt > subfile.txt"
    end
    
    desc "Create new array"
    task :new_array => ["subfile.txt"] do
    ARRAY=Array.new
    end
    
    desc "Add elements to array"
    task :add_elements => [:new_array] do
    File.open("infile.txt").each do |line|
    ARRAY.push(line)
    end
    end
    
    ARRAY.each do |element|
    file "#{element}.txt" => [:add_elements] do
    sh 'bash command to create #{element}.txt"'
    end
    end
    

    不幸的是,我收到错误:

    NameError: uninitialized constant ARRAY
    

    我认为问题来自于我的ARRAY从一开始就没有设置因为创建了中间脚本而且因为我对前一个任务(:add_elements)的依赖是文件任务file "#{element}.txt" => [:add_elements] do而不是我使用ARRAY ARRAY.each do |element|的实际行。

    解决这个问题的方法是:

    multitask :create_element_file => [:add_elements] do
    ARRAY.each do |element|
    file_task
    end
    
    def file_task
    file "#{element}.txt" do
    sh 'bash command to create #{element}.txt"'
    end
    

    然而,它现在抱怨:

    NameError: undefined local variable or method `element' for main:Object
    

    有没有办法明确设置在脚本中创建的数组?我的依赖项出错了吗?我称之为任务的方式?

    任何帮助表示感谢。

    =============================================== ============================

    使用我选择的解决方案进行编辑:

    我发现我的rakefile变得太复杂,所以我决定编写多个连接的rake文件。

    rakefile1.rake:

    file "subfile.txt" => ["infile.txt"] do
    sh "grep '>' infile.txt > subfile.txt"
    end
    
    desc "Create subfile"
    task :create_subfile => ["subfile.txt"] do
    puts "Subfile created"
    end
    
    desc "Call next rakefile"
    task :next_rakefile => [:create_subfile] do
    sh "rake -f rakefile2.rake --trace"
    end
    

    rakefile2.rake:

    ARRAY=File.readlines("subfile.txt").each {|locus| locus.chomp!}
    
    ARRAY.each do |element|
    file "#{element}.txt" => ["subfile.txt"] do
    sh "bash command to create #{element}.txt"
    end
    

2 个答案:

答案 0 :(得分:1)

您描述的问题之所以出现是因为elementeach块中的局部变量。您需要将变量传递给file_task方法,如下所示:

multitask :create_element_file => [:add_elements] do
  ARRAY.each do |element|
    file_task(element)
  end
end

def file_task(element)
  file "#{element}.txt" do
    sh 'bash command to create #{element}.txt"'
  end
end

答案 1 :(得分:1)

我认为你混淆了常量和全局变量。这里ARRAY是一个常量(当谈论一个内容被修改但仍然有效的对象时,这很奇怪)但是你无法在任务中访问它,因为这样做你必须要么通过它作为参数或(我认为你打算做什么)使它成为一个全局变量The letter a is in bAseBall 2 time(s) The letter s is in bAseBall 1 time(s) The letter b is in bAseBall 2 time(s) The letter e is in bAseBall 1 time(s) The letter l is in bAseBall 2 time(s) (全局变量通常被认为是不好的做法)

解释错误:
  - 第一个($array)指的是ARRAY属于Main的事实,它不能从NameError: uninitialized constant ARRAY访问。
  - 第二个与Main > task > File.open相同的问题,在

element

ARRAY.each do |element| file_task end 属于element,无法从ARRAY.each访问。再次,您必须将其作为参数传递或使其全局(并且全局变量仍然是一件坏事!)