1

If I want to run a bunch of ruby scripts (super similar, with maybe a number changed as a commandline argument) and still have them output to stdout, is there a way to do this?

i.e a script to run these:

 ruby program1.rb input_1.txt
 ruby program1.rb input_2.txt
 ruby program1.rb input_3.txt

like

 (1..3).each do |i|
 ruby program1.rb input_#{i}'
 end

in another script, so I can just run that script and see the output in a terminal from all 3 runs?

EDIT:

I'm struggling to implement the second highest voted suggested answer.

I don't have a main function within my program1.rb, whereas the suggested answer has one.

I've tried this, for script.rb:

require "program1.rb"
(1..6).each do |i|
 driver("cmd_line_arg_#{i}","cmd_line_arg2")
end

but no luck. Is that right?

asked Mar 29, 2015 at 9:26
4
  • possible duplicate of Running another ruby script from a ruby script Commented Mar 29, 2015 at 9:29
  • is program1 something external or something that you did wrote? If its yours, why are you not simply requiring it & calling its method? Commented Mar 29, 2015 at 9:49
  • I wrote program1, but I don't want to call its methods. It runs as a script, so whilst not very object-oriented, I want to just run it with different arguments. The 'main stuff' runs outside of any method. Commented Mar 29, 2015 at 9:56
  • Ok. When you says "no luck", could you show the error tht you get ? Commented Mar 29, 2015 at 10:12

2 Answers 2

5

You can use load to run the script you need (the difference between load and require is that require will not run the script again if it has already been loaded).

To make each run have different arguments (given that they are read from the ARGV variable), you need to override the ARGV variable:

(1..6).each do |i|
 ARGV = ["cmd_line_arg_#{i}","cmd_line_arg2"]
 load 'program1.rb'
end
answered Mar 29, 2015 at 11:31
0
# script_runner.rb
require_relative 'program_1'
module ScriptRunner
 class << self
 def run
 ARGV.each do | file |
 SomeClass.new(file).process
 end
 end
 end
end
ScriptRunner.run

.

# programe_1.rb
class SomeClass
 attr_reader :file_path
 def initialize(file_path)
 @file_path = file_path
 end
 def process
 puts File.open(file_path).read
 end
end

Doing something like the code shown above would allow you to run:

ruby script_runner.rb input_1.txt input_2.txt input_3.txt

from the command line - useful if your input files change. Or even:

ruby script_runner.rb *.txt

if you want to run it on all text files. Or:

ruby script_runner.rb inputs/*

if you want to run it on all files in a specific dir (in this case called 'inputs').

This assumes whatever is in program_1.rb is not just a block of procedural code and instead provides some object (class) that encapsulates the logic you want to use on each file,meaning you can require program_1.rb once and then use the object it provides as many times as you like, otherwise you'll need to use #load:

# script_runner.rb
module ScriptRunner
 class << self
 def run
 ARGV.each do | file |
 load('program_1.rb', file)
 end
 end
 end
end
ScriptRunner.run

.

# program_1.rb
puts File.open(ARGV[0]).read
answered Mar 29, 2015 at 13:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.