Скрипт Ruby запускается из определенной строки или метода
Допустим, у меня есть сценарий:
!#usr/bin/ruby
# step 1
puts "That's first"
# some code
#step 2
puts "That's second"
# some code
Есть ли способ передать ARGV скрипту, который начнет выполнение с определенной строки (или шага, или класса, или чего-то еще)?
Например, выполнение $ ruby script.rb -s 2
начнется со второго шага.
У меня есть мысль о разборе аргумента с помощью ifelse
, но в этом случае скрипт станет намного сложнее и совсем не сухим.
Есть идеи?
3 ответа:
Есть способы, как показывает ответ Макса, но вы не должны этого делать. Были вопросы о заявлении Гото для Руби, прежде чем вы узнали. Почему вы должны возвращаться к методам, используемым в BASIC ? Покажите нам использование, и мы покажем вам лучшие способы.
Если вы начинаете с Ruby и программирования, вы можете просто использовать процедурный способ программирования, такой как
def print_a puts "a" end
И позже, независимо от того, где строка "puts a" переместилась между вами последнее обновление
print_a
Если вы более опытные вы будете использовать это с комбинацией объектно-ориентированного или функционального способа программирования.
Мне приходит на ум одно акцептивное употребление: условные require's или load'S
Надеюсь, я заставил тебя пересмотреть свой вопрос..if condition require ./mycode_only_to be_executed_in_this_case.rb' end
Редактировать после комментария op
Пример, на который вы ссылаетесь, не сухой, это первое, что я замечаю. См. https://en.wikipedia.org/wiki/Don ' t_repeat_yourself для определения сухогоВот какой я я бы сделал из этого, я все еще использую методы, чтобы охватить мой код, так что это код, который я могу повторно использовать и имеет только одну цель и является тестируемым: подключение к сайту. Никакого дубликата кода, так сухо.
require 'watir' def goto_site site a = Watir::Browser.new :chrome a.goto site # a lot of code down here a.close end goto_site 'site.com'
Плохие вещи случаются, когда вы используете GOTO.
Вот предложение, которое может решить вашу проблему немного более элегантным способом:Определите свои шаги в ' 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_steps.rb
:# launch_steps.rb require_relative 'define_steps' launch_steps! puts "-----------------" launch_steps!(2,3)
Выводит :
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!
без параметров выполняется каждый определенный шаг,launch_steps!(min,max)
выполняется каждый шаг междуmin
иmax
,launch_steps!(min)
бежит Шагmin
и каждый шаг после.
Вот программа
run_from_line.rb
, которая принимает три аргумента: путь, начальная строка и конечная строка. Конечная строка необязательна и по умолчанию равна -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
С этим скриптом в
test.rb
:puts "line 0" puts "line 1" puts "line 2"
Тестирование:
> ruby run_from_line.rb test.rb 1 line 1 line 2 > ruby run_from_line.rb test.rb 1 1 line 1
Если вы хотите сделать этот сценарий общесистемным, запустите
chmod a+x run_from_line.rb
затемsudo mv run_from_line.rb /usr/local/sbin