【问题标题】:loop through newly created array in ruby rake循环遍历 ruby​​ rake 中新创建的数组
【发布时间】:2018-06-17 21:43:55
【问题描述】:

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

  1. 使用 grep 从文件创建子文件
  2. 创建一个名为 ARRAY 的新空数组
  3. 将子文件的每一行作为 ARRAY 中的元素推送
  4. 循环遍历 ARRAY 的每个元素并为每个元素创建一个文件 (#{element}.txt)。

到目前为止我所拥有的:

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 变得过于复杂,所以我决定编写多个连接的 rakefile。

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

【问题讨论】:

    标签: arrays ruby loops rake


    【解决方案1】:

    我认为您混淆了常量和全局变量。这里 ARRAY 是一个常量(在谈论修改内容的对象时这很奇怪,但这仍然有效)但您不能在任务中访问它,因为这样做您必须将其作为参数传递或 (我认为这就是您打算做的)使其成为全局变量$array(尽管全局变量通常被认为是不好的做法)

    解释错误:
    - 第一个(NameError: uninitialized constant ARRAY)指的是ARRAY属于Main,不能从Main > task > File.open访问。
    - 第二个和element有同样的问题,在

    ARRAY.each do |element|
        file_task
    end
    

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

    【讨论】:

    • 感谢您的回答,我的问题来了,我的参数不适用于我正在处理的环境(不是我在这里使用正确的命名法)。我编辑了我的问题以解释我是如何解决我的问题的。
    【解决方案2】:

    出现您描述的问题是因为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
    

    【讨论】:

    • 确实,这防止了第二个错误被抛出。
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多