4

I am mostly interested in the theory of this than an actual code solution. How can I have one main ruby script invoking other scripts and sharing variables between each other? I am a bit confused.. Do I need to use environmental vars, session vars, methods, models, controllers, what is the best way to do it!!?

4

3 回答 3

5

假设您有一个script.rb,其中包含以下内容:

$var = :value
def get; A end
load 'another_script.rb'
get  # Will it succeed?

当您运行时ruby script.rb,您会生成一个 Ruby 进程,该进程将读取script.rb并执行每一行的内容。Ruby 解释器有一个执行状态,它保存着诸如对象数据、引用它们的变量、它们所属的范围、您当前所处的方法等信息。

当解释器读取该$var = :value行时,它会修改自己的状态。它存储一个引用新创建的符号对象的全局变量。接下来,它定义了一个方法,该方法将返回常量引用的A值。此时调用它会引发 a NameError,因为该常量不存在。当它到达该load 'another_script.rb'行时,它类似于 running ruby another_script.rb,除了没有启动第二个进程。脚本的内容在同一个执行上下文中被读取和解释。

假设another_script.rb包含以下内容:

$var = :changed
class A; end

$var以前引用符号的变量:value现在将引用:changed符号。然后,Class将创建一个对象并将其分配给新A常量。

加载此脚本后,调用get将成功。另一个含义是顺序很重要。例如:

load 'another_script.rb'
$var = :value

任何another_script.rb设置$var都将丢失,因为它将在执行完成后立即被覆盖。

不管你有多少脚本loadrequire或者eval,只要它们运行在同一个进程上,它们总是会共享相同的数据。只有局部变量不会在文件之间共享。当您想在两个不同的Ruby 解释器之间共享数据时,事情会变得复杂:

ruby script.rb &
ruby another_script.rb &

在这种情况下,您必须使用进程间通信

于 2012-05-03T12:08:33.447 回答
3

取决于您调用.

通常,当“一个脚本调用另一个脚本”时,它基本上与一个“进程启动另一个进程”相同。因此,您将使用进程间通信,而不是真正特定于 Ruby。是的,环境变量等简单的东西是传递信息的一种方式,但可能会考虑文件、套接字等。

OTOH,如果您想在另一个“脚本”(.rb) 文件中使用Ruby 代码,请按照第一个答案指出的那样加载/要求它。这使得方法 (def f)、常量 (CTE)、实例变量 (@f) 和全局变量 ($G) 在您从中加载的文件中可用;但不是局部变量(如 x=3)。

在特殊情况下,您也可以使用“eval”来访问局部变量 - 但我认为这不适用于您的场景。

于 2012-05-03T11:50:33.250 回答
3

如果您希望两个 Ruby 进程进行通信(即使它们运行在不同的机器上),那么Druby就是内置方式。

于 2012-05-03T12:58:10.193 回答