Ruby 脚本从特定行或方法开始
Ruby script start from a specific line or method
假设我有一个脚本:
!#usr/bin/ruby
# step 1
puts "That's first"
# some code
#step 2
puts "That's second"
# some code
有没有办法将 ARGV 传递给将从特定行(或步骤,或 class 或其他)开始执行的脚本?
例如执行$ ruby script.rb -s 2
将从第二步开始。
我考虑过使用 if\else
解析参数,但在这种情况下,脚本将变得更加复杂,而且根本不是 DRY。
有什么想法吗?
这是一个程序 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
max 的答案告诉你有很多方法,但你不应该这样做。
在你知道之前,有关于 Ruby 的 goto 语句的问题。
为什么要回到 BASIC 中使用的技术?告诉我们一个用法,我们会告诉你更好的方法。
如果您是从 Ruby 开始编程,您可以使用像
这样的程序化编程方式
def print_a
puts "a"
end
及以后,无论 "puts a" 行移动到上次更新之间的什么位置
print_a
如果您更有经验,您将结合面向对象或函数式编程方式使用它。
我想到了一个可接受的用法:有条件的 require 或 load
if condition
require ./mycode_only_to be_executed_in_this_case.rb'
end
希望我让你重新思考你的问题..
评论操作后编辑
您提到的示例不是 DRY,这是我注意到的第一件事。
有关 DRY
的定义,请参阅 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'
Bad things 使用 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
以及之后的每一步。
假设我有一个脚本:
!#usr/bin/ruby
# step 1
puts "That's first"
# some code
#step 2
puts "That's second"
# some code
有没有办法将 ARGV 传递给将从特定行(或步骤,或 class 或其他)开始执行的脚本?
例如执行$ ruby script.rb -s 2
将从第二步开始。
我考虑过使用 if\else
解析参数,但在这种情况下,脚本将变得更加复杂,而且根本不是 DRY。
有什么想法吗?
这是一个程序 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
max 的答案告诉你有很多方法,但你不应该这样做。 在你知道之前,有关于 Ruby 的 goto 语句的问题。 为什么要回到 BASIC 中使用的技术?告诉我们一个用法,我们会告诉你更好的方法。
如果您是从 Ruby 开始编程,您可以使用像
这样的程序化编程方式def print_a
puts "a"
end
及以后,无论 "puts a" 行移动到上次更新之间的什么位置
print_a
如果您更有经验,您将结合面向对象或函数式编程方式使用它。
我想到了一个可接受的用法:有条件的 require 或 load
if condition
require ./mycode_only_to be_executed_in_this_case.rb'
end
希望我让你重新思考你的问题..
评论操作后编辑
您提到的示例不是 DRY,这是我注意到的第一件事。 有关 DRY
的定义,请参阅 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'
Bad things 使用 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
以及之后的每一步。