如何在ruby脚本之间传递变量?

时间:2022-09-23 22:52:16

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!!?

我最感兴趣的是这个理论,而不是一个实际的代码解决方案。如何让一个主要的ruby脚本调用其他脚本并在彼此之间共享变量?我有点糊涂了。我是否需要使用环境vars、会话vars、方法、模型、控制器,最好的方法是什么?

3 个解决方案

#1


5  

Let's assume you have a script.rb, which contains this:

假设您有一个脚本。rb,其中包含:

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

When you run ruby script.rb, you spawn a Ruby process which will read the contents of script.rb and execute every line. The Ruby interpreter has an execution state which holds information such as object data, the variables that reference them, which scope they belong to, which method you're currently in and so much more.

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

When the interpreter reads the $var = :value line, it modifies its own state. It stores a global variable which references the newly-created symbol object. Next, it defines a method which will return the value referenced by the A constant. Calling it at this point will raise a NameError, since the constant does not exist. When it reaches the load 'another_script.rb' line, it is analogous to running ruby another_script.rb, except no second process is started. The contents of the script are read and interpreted within the same execution context.

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

Suppose another_script.rb contains the following:

假设another_script。rb包含以下:

$var = :changed
class A; end

The $var variable, which previously referenced the :value symbol, will now reference the :changed symbol. Then, a Class object will be created and assigned to the new A constant.

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

After loading this script, the call to get will succeed. Another implication is that order matters. For example:

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

load 'another_script.rb'
$var = :value

Whatever another_script.rb set $var to will be lost since it will be overridden immediately after it has finished executing.

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

No matter how many scripts you load, require or eval, as long as they are running on the same process, they will always share the same data. Only local variables will not be shared between files. Things get complicated when you want to share data between two different Ruby interpreters:

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

ruby script.rb &
ruby another_script.rb &

In that case, you have to use inter-process communication.

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

#2


3  

If you want two Ruby processes to communicate (even if they are running on different machines), then Druby is the built in way.

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

#3


3  

Depends on what you mean by invoking.

取决于你调用的意思。

Generally when "a script invokes another script" it's basically the same as one "process starting another process". So there you would use inter-process communcation, not really specific to Ruby.. Yes, simple things like environment variables are one way to pass info down, but might consider files, sockets, etc..

通常,当“一个脚本调用另一个脚本”时,它基本上与一个“进程启动另一个进程”相同。所以你可以使用进程间通信,而不是Ruby特有的。是的,像环境变量这样简单的东西是传递信息的一种方式,但是可以考虑文件、套接字等等。

OTOH, if you want to use Ruby code from in one "script" (.rb) file in another, you load/require it as the first answer pointed out. This makes the methods (def f), constants(CTE), instance variables(@f) and global variables($G) available in the file you're loading from; but not the local variables (like x=3).

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

In special cases, you can want to use 'eval' to access local variables too - but I don't think that's applicable in your scenario.

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

#1


5  

Let's assume you have a script.rb, which contains this:

假设您有一个脚本。rb,其中包含:

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

When you run ruby script.rb, you spawn a Ruby process which will read the contents of script.rb and execute every line. The Ruby interpreter has an execution state which holds information such as object data, the variables that reference them, which scope they belong to, which method you're currently in and so much more.

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

When the interpreter reads the $var = :value line, it modifies its own state. It stores a global variable which references the newly-created symbol object. Next, it defines a method which will return the value referenced by the A constant. Calling it at this point will raise a NameError, since the constant does not exist. When it reaches the load 'another_script.rb' line, it is analogous to running ruby another_script.rb, except no second process is started. The contents of the script are read and interpreted within the same execution context.

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

Suppose another_script.rb contains the following:

假设another_script。rb包含以下:

$var = :changed
class A; end

The $var variable, which previously referenced the :value symbol, will now reference the :changed symbol. Then, a Class object will be created and assigned to the new A constant.

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

After loading this script, the call to get will succeed. Another implication is that order matters. For example:

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

load 'another_script.rb'
$var = :value

Whatever another_script.rb set $var to will be lost since it will be overridden immediately after it has finished executing.

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

No matter how many scripts you load, require or eval, as long as they are running on the same process, they will always share the same data. Only local variables will not be shared between files. Things get complicated when you want to share data between two different Ruby interpreters:

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

ruby script.rb &
ruby another_script.rb &

In that case, you have to use inter-process communication.

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

#2


3  

If you want two Ruby processes to communicate (even if they are running on different machines), then Druby is the built in way.

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

#3


3  

Depends on what you mean by invoking.

取决于你调用的意思。

Generally when "a script invokes another script" it's basically the same as one "process starting another process". So there you would use inter-process communcation, not really specific to Ruby.. Yes, simple things like environment variables are one way to pass info down, but might consider files, sockets, etc..

通常,当“一个脚本调用另一个脚本”时,它基本上与一个“进程启动另一个进程”相同。所以你可以使用进程间通信,而不是Ruby特有的。是的,像环境变量这样简单的东西是传递信息的一种方式,但是可以考虑文件、套接字等等。

OTOH, if you want to use Ruby code from in one "script" (.rb) file in another, you load/require it as the first answer pointed out. This makes the methods (def f), constants(CTE), instance variables(@f) and global variables($G) available in the file you're loading from; but not the local variables (like x=3).

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

In special cases, you can want to use 'eval' to access local variables too - but I don't think that's applicable in your scenario.

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