从ruby脚本运行另一个ruby脚本

时间:2010-04-14 05:38:15

标签: ruby

在ruby中,是否可以指定使用与原始脚本运行相同的ruby解释器来调用另一个ruby脚本?

例如,如果a.rb运行b.rb几次,是否可以替换

system("ruby", "b.rb", "foo", "bar")

类似

run_ruby("b.rb", "foo", "bar")

因此,如果您在原始广告上使用ruby1.9.1 a.rb,则会在b.rb上使用ruby1.9.1,但如果您在原始版本上使用了ruby a.rbruby会用于b.rb?

我不想使用shebangs,因为我希望能够在不同的计算机上运行,​​其中一些计算机没有/usr/bin/env

编辑:我不是指loadrequire之类的,而是产生新进程(因此我可以使用多个CPU)。

7 个答案:

答案 0 :(得分:21)

require "b.rb"

将执行b.rb的内容(你打电话给“.rb”,并有一个搜索路径)。在您的情况下,您可能会执行以下操作:

a.rb:

require "b.rb";
b("Hello", "world")

b.rb:

def b(first, second)
  puts first + ", " + second
end

请注意,如果您使用require,Ruby只会加载并执行一次文件(每次调用load时都会重新加载),但您可以调用文件中定义的方法你想要的时间。

随着事情变得越来越复杂,您将希望转向面向对象的设计。

编辑:在这种情况下,你应该研究Ruby线程。一个简单的例子是:

a.rb:

require "b";
t1 = Thread.new{b("Hello", "world");}
t2 = Thread.new{b("Hello", "galaxy");}
t1.join
t2.join

b.rb:

def b(first, second)
  10.times {
    puts first + ", " + second;
    sleep(0.1);
  }
end

答案 1 :(得分:11)

答案 2 :(得分:7)

需要技巧是一个好主意,假设有问题的脚本没有阻止尝试重新定义您可能已经设置的任何常量,或者调用对象上的方法,您可能已经修改了运行时猴子以不再遵守其标准合同。< / p>

在任何一种情况下,问题都不是脚本本身的代码。显示出良好的举止,将常量放在命名空间中,并且不要破坏性地修补运行时。

要确保有问题的脚本不会破坏调用脚本的运行时,并防止它可能在某处调用Kernel / Process.exit(),请尝试以下

pid=Process.fork do
    require 'script.rb'
    Process.exit
end
ignored, status = Process.waitpid2(pid, Process::WNOHANG)
puts "script.rb PID #{pid} exited, exit status: #{status.exitstatus}" 

对于更高级的内容,例如写入stdin流或从stdout或stderr流中读取,请使用Open4 gem。

答案 3 :(得分:3)

如果您只想在现有流程的上下文中运行脚本,也可以执行此操作

eval File.read("/path/to/your/script.rb")

不确定您的用例是什么,但这可能很有用,例如,如果您打开Rails控制台并且您想要在临时文件中执行某些代码,但又不想继续复制整个块的代码进入你的控制台。

答案 4 :(得分:1)

答案 5 :(得分:1)

这是我用过的

/myapp/script/main_script.rb

<小时/> 加载导轨env,仅在您需要

ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")

从main_script.rb

中运行其他从属脚本
require File.expand_path(File.dirname(__FILE__) + "/../script/populate_wh_grape_varieties_table.rb")

答案 6 :(得分:0)

JRuby成名的Charles Nutter是suggesting Kernel#ruby方法,使用与您当前使用的相同的Ruby实现来调用Ruby脚本。

修改:提案被拒绝。 Matz说MVM(多个虚拟机)可能提供解决方案。