Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby script start from a specific line or method

Let's say i have a script:

!#usr/bin/ruby

# step 1
puts "That's first"
# some code

#step 2
puts "That's second"
# some code

Is there a way to pass ARGV to script that will start execution from a specific line (or step, or class, or whatever)? For example executing $ ruby script.rb -s 2 will start from second step.

I have a thought about parsing the argument with if\else, but in this case script will become much more complicated and not DRY at all.

Any ideas?

like image 645
nesaulov Avatar asked Dec 19 '22 11:12

nesaulov


2 Answers

Bad things happen when you use GOTO.

Here's a proposal that could solve your problem in a bit more elegant way :

Define your steps in 'define_steps.rb' :

# define_steps.rb
#####################################################
@steps = []

def step(i, &block)
  @steps[i] = block
end

def launch_steps!(min = 0, max = @steps.size - 1)
  @steps[min..max].each.with_index(min) do |block, i|
    if block
      puts "Launching step #{i}"
      block.call
    end
  end
end
#####################################################

step 1 do
  puts 'Step 1 with lots of code'
end

step 2 do
  puts 'Step 2 with lots of code'
end

step 3 do
  puts 'Step 3 with lots of code'
end

step 4 do
  puts 'Step 4 with lots of code'
end

Launch them separately with launch_steps.rb :

# launch_steps.rb
require_relative 'define_steps'

launch_steps!
puts "-----------------"
launch_steps!(2,3)

It outputs :

Launching step 1
Step 1 with lots of code
Launching step 2
Step 2 with lots of code
Launching step 3
Step 3 with lots of code
Launching step 4
Step 4 with lots of code
-----------------
Launching step 2
Step 2 with lots of code
Launching step 3
Step 3 with lots of code

launch_steps! without parameters runs every defined step, launch_steps!(min,max) runs every step between min and max, launch_steps!(min) runs step min and every step after.

like image 133
Eric Duminil Avatar answered Jan 06 '23 20:01

Eric Duminil


Here's a program run_from_line.rb which accepts three arguments: path and start line, and end line. End line is optional and defaults to -1.

#/usr/bin/env ruby

path = ARGV.shift
program_text = File.readlines(path)
start_line = ARGV.shift.to_i;
end_line = ARGV.shift || '-1'
end_line = end_line.to_i

selected_code = program_text[start_line..end_line].join
eval selected_code

With this script at test.rb:

puts "line 0"
puts "line 1"
puts "line 2"

Testing:

> ruby run_from_line.rb test.rb 1
line 1
line 2

> ruby run_from_line.rb test.rb 1 1
line 1

If you want to make this a system-wide script, run chmod a+x run_from_line.rb then sudo mv run_from_line.rb /usr/local/sbin

like image 31
max pleaner Avatar answered Jan 06 '23 22:01

max pleaner