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!!?
3 回答
假设您有一个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
都将丢失,因为它将在执行完成后立即被覆盖。
不管你有多少脚本load
,require
或者eval
,只要它们运行在同一个进程上,它们总是会共享相同的数据。只有局部变量不会在文件之间共享。当您想在两个不同的Ruby 解释器之间共享数据时,事情会变得复杂:
ruby script.rb &
ruby another_script.rb &
在这种情况下,您必须使用进程间通信。
取决于您调用.
通常,当“一个脚本调用另一个脚本”时,它基本上与一个“进程启动另一个进程”相同。因此,您将使用进程间通信,而不是真正特定于 Ruby。是的,环境变量等简单的东西是传递信息的一种方式,但可能会考虑文件、套接字等。
OTOH,如果您想在另一个“脚本”(.rb) 文件中使用Ruby 代码,请按照第一个答案指出的那样加载/要求它。这使得方法 (def f)、常量 (CTE)、实例变量 (@f) 和全局变量 ($G) 在您从中加载的文件中可用;但不是局部变量(如 x=3)。
在特殊情况下,您也可以使用“eval”来访问局部变量 - 但我认为这不适用于您的场景。
如果您希望两个 Ruby 进程进行通信(即使它们运行在不同的机器上),那么Druby就是内置方式。