我最感兴趣的是这个理论,而不是实际的代码解决方案。如何让一个主ruby脚本调用其他脚本并在彼此之间共享变量?我有点困惑..我是否需要使用环境变量,会话变量,方法,模型,控制器,这是最好的方法!!?
答案 0 :(得分: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
常量引用的值。此时调用它将引发NameError
,因为该常量不存在。当它到达load 'another_script.rb'
行时,它类似于运行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
将丢失,因为它将在执行完毕后立即被覆盖。
无论您load
,require
或eval
有多少个脚本,只要它们在同一个流程上运行,它们始终共享相同的数据。 Only local variables will not be shared between files。当您想要在两个不同的 Ruby解释器之间共享数据时,事情会变得复杂:
ruby script.rb &
ruby another_script.rb &
在这种情况下,您必须使用inter-process communication。
答案 1 :(得分:3)
取决于调用的含义。
通常当“脚本调用另一个脚本”时,它基本上与一个“启动另一个进程的进程”相同。所以你会使用进程间通信,而不是特定于Ruby。是的,像环境变量之类的简单事情是传递信息的一种方式,但可能会考虑文件,套接字等。
OTOH,如果你想在另一个“脚本”(.rb)文件中使用 Ruby代码,你可以加载/要求它作为指出的第一个答案。 这使得您加载的文件中的方法(def f),常量(CTE),实例变量(@f)和全局变量($ G)可用;但不是局部变量(如x = 3)。
在特殊情况下,您可以使用'eval'来访问本地变量 - 但我认为这不适用于您的场景。
答案 2 :(得分:3)
如果你想要两个Ruby进程进行通信(即使它们在不同的机器上运行),那么Druby就是内置的方式。