I'm not sure if the question title makes sense, but here's what I'm trying to do.
I have a Rakefile that contains an array. I want to be able to use another ruby script to read the Rakefile, add something to that array, sort it, then write it back to the Rakefile in place.
In pseudo code, this is what I'm essentially trying to achieve:
rake_file = load file('Rakefile')
rake_file.array += 'new data'
rake_file.array.sort!
file.write Rakefile
The Rakefile contains many arrays and tasks, so I can't treat it like a regular text file and just append a value to the file and sort, hence why my idea is to load it and edit the array as above.
Is this even possible?
I can't treat it like a regular text file
You then need to learn ANTLR, create a Ruby grammar, generate a parser, and write a Java or C# or Python tree walker to edit your array. Simple :-)
I have imagined a quick and simple solution. The array is kept in a file, say array_source.rb
:
a = [1, 5, 10, 15]
This file can be manually edited, or, if you need to programmatically generate the data, created with a script, say create_array_source.rb :
# update the file containing the array of data in text representation
array_source_name = 'array_source.rb'
a = [1, 5, 10, 15]
# add new data
[2, 6, 11, 16].each { | e | a << e }
puts a.join(' ')
# Write it to a file
File.open(array_source_name, 'w') do | out |
# to avoid a very long single line, the data is pretty printed
groups = []
a.sort.each_slice(4) { | slice | groups << slice.join(', ') }
out.puts ' ['
out.print ' '
out.puts groups.join(",\n ")
out.puts ' ]'
end
puts "#{array_source_name} has been created"
Execution :
$ ruby -w create_array_source.rb
1 5 10 15 2 6 11 16
array_source.rb has been created
File array_source.rb after :
[
1, 2, 5, 6,
10, 11, 15, 16
]
In the Rakefile, the array to update is placed between two specific markers :
task :default => [:ta, :tb] do
end
task :ta do
# $$insert array after$$
a = [1, 5, 10, 15]
# $$insert array before$$
# do something with a
end
task :tb do
# do something
end
So it is easy to write a script which processes it as a text file, splitting the lines into two parts :
and then rewrite the file by concatenating the first part, the array and the second part :
# modify a specific array in a Rakefile
rakefile_name = 'Rakefile'
array_source_name = 'array_source.rb'
lines = IO.readlines(rakefile_name)
insert_marker_after_seen = false
insert_marker_before_seen = false
lines1 = []
lines2 = IO.readlines(array_source_name)
lines3 = []
# split the Rakefile
lines.each do | line |
case
when insert_marker_after_seen == false
lines1 << line
if line.include?('$$insert array after$$')
then
insert_marker_after_seen = true
end
when ! insert_marker_before_seen
# ignore array lines
if line.include?('$$insert array before$$')
then
insert_marker_before_seen = true
lines3 << line
end
else
lines3 << line
end
end
# Rewrite the Rakefile
File.open(rakefile_name, 'w') do | out |
[ lines1, lines2, lines3 ].each do | lines_group |
lines_group.each { | line | out.puts line }
end
end
puts "#{rakefile_name} has been updated with #{array_source_name}"
Execution :
$ ruby -w modify_rakefile.rb
Rakefile has been updated with array_source.rb
Rakefile after :
task :default => [:ta, :tb] do
end
task :ta do
# $$insert array after$$
[
1, 2, 5, 6,
10, 11, 15, 16
]
# $$insert array before$$
# do something with a
end
task :tb do
# do something
end