Ruby脚本从特定的行或方法开始

Ruby脚本从特定的行或方法开始,ruby,command-line-interface,argv,Ruby,Command Line Interface,Argv,假设我有一个脚本: !#usr/bin/ruby # step 1 puts "That's first" # some code #step 2 puts "That's second" # some code 有没有一种方法可以将ARGV传递给将从特定行(或步骤、类或其他)开始执行的脚本? 例如,执行$ruby script.rb-s2将从第二步开始 我考虑过用if\else解析参数,但在这种情况下,脚本将变得更加复杂,一点也不枯燥 有什么想法吗?这里有一个程序从\u line.rb运

假设我有一个脚本:

!#usr/bin/ruby

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

#step 2
puts "That's second"
# some code
有没有一种方法可以将ARGV传递给将从特定行(或步骤、类或其他)开始执行的脚本? 例如,执行
$ruby script.rb-s2
将从第二步开始

我考虑过用
if\else
解析参数,但在这种情况下,脚本将变得更加复杂,一点也不枯燥


有什么想法吗?

这里有一个程序
从\u line.rb运行\u,它接受三个参数:path和start line,以及end line。结束行是可选的,默认为-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\u from\u line.rb
然后
sudo mv run\u from\u line.rb/usr/local/sbin

max的答案告诉你一些方法,但你不应该这么做。 在你知道之前,关于Ruby的goto声明有很多问题。 为什么要回到BASIC中使用的技术?告诉我们一个用法,我们会告诉你更好的方法

如果您刚开始使用Ruby和编程,您可以使用一种程序化的编程方式,如

def print_a
  puts "a"
end
之后,无论“放置a”的行移到哪里,都会在上次更新之间

print_a
如果您更有经验,您将结合使用面向对象或函数式编程方式

我想到了一个接受用法:条件需求或负载

if condition
  require ./mycode_only_to be_executed_in_this_case.rb'
end
希望我能让你重新思考你的问题

评论后编辑

你提到的例子并不枯燥,这是我注意到的第一件事。 请参见“你自己重复”了解干燥的定义

在这里,我将利用它,我仍然使用一个方法来封装我的代码,这样我就可以重用代码,并且只有一个目的是可以测试的:连接到一个站点。没有重复的代码,所以干燥

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\u步骤分别启动它们。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\u步骤不带参数运行每个定义的步骤,
启动\u步骤!(最小,最大)
min
max
之间运行每个步骤,
启动步骤!(min)
运行步骤
min
以及之后的每一步。

shift
非常繁重。为什么不
path=ARGV[0]
path,start\l,end\u l=ARGV
?由于ARGV干扰GET,人们经常感到困惑。这两个方面有何关联?一个来自STDIN,另一个来自ARGV。这是一个有趣的观点,
Kernel#gets
确实如此,但我从未见过有人混淆这两件事。这实际上是一个很好的功能,因为你可以通过命令行指定输入文件,即使是不明确允许的程序。我看到一些人感到困惑,因为他们的get.chomp没有暂停请求输入。这是一个很酷的建议。谢谢彼得,你的方法很深入。在我的例子中,我有一个运行watir webdriver并检查多个实例的脚本。所以我想知道,如果不需要检查上一步,是否有一种方法可以从特定步骤执行脚本。我编辑了我的答案,请看一看。这取决于
#这里的许多代码从一个方法到另一个方法是否相同。@peter:DRY需要不同的结构,因为
转到站点(站点)
需要根据
站点调用不同的代码。现在,它只节省了几行代码,并不能真正帮助解决最初的问题。@EricDuminil我必须查看代码的其余部分,以决定如何保持它干燥,但重要的是,方法适合这里,而不是goto-line解决方案,Eric的DSL解决方案也是某种方法,Max solution很有意思,但不可取,它们都有一个来自Me的+1。这里有一点DSL(特定于域的语言),这使代码非常容易理解。美好的