I have yet another question on Ruby. What I want to do is to:
What I have so far:
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
Unfortunately, I get the error:
NameError: uninitialized constant ARRAY
I think the problem comes from the fact that my ARRAY has not been set from the beginning because created mid-script and because my dependency on the previous task (:add_elements) is with the file task file "#{element}.txt" => [:add_elements] do
and not the actual line where I use the ARRAY ARRAY.each do |element|
.
A way around it would be:
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
However, it is now complaining about:
NameError: undefined local variable or method `element' for main:Object
Is there a way to definitively set an array that is created mid-script? Am I doing something wrong with my dependencies? The way I call my tasks?
Any help appreciated.
===========================================================================
EDIT with my chosen solution:
I found my rakefile was becoming too complicated so I decided to write multiple connected rakefiles.
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
I think you're confusing constants and global variables. Here ARRAY is a constant (which is weird imo when talking about an object which content is modified, but that's still valid) but you can't access it within the task, because to do so you must either pass it as a parameter or (I think that's what you intended to do) make it a global variable $array
(global variables are usually considered bad practice though)
To explain the errors :
- The first one (NameError: uninitialized constant ARRAY
) Refers to the fact that ARRAY belongs to Main, it's not accessible from Main > task > File.open
.
- The second one is the same problem with element
, in
ARRAY.each do |element|
file_task
end
element
belongs to ARRAY.each
and is not accessible from file_task
. Once again, you must either pass it as a parameter or make it global (and global variables are still a bad thing!)