如何在Ruby中通过引用传递?

目前我正在开发Ruby中的Watcher类,除其他外,它能够找到切换信号的周期持续时间。 这通常很简单,但我面临的一个问题是,Ruby显然是按值传递所有参数。 在网上进行研究时,我发现了很多关于“通过价值传递”和“通过参考传递”实际上是什么的不同讨论,但没有实际的“如何”。 来自C / C ++背景,对我而言,这是编程/脚本语言的重要组成部分。

我写的课程的相关部分如下所示。 方法Watcher :: watchToggling()是我遇到麻烦的方法。 作为参数, aVariable应该是我正在测量周期持续时间的值的参考。

 class Watcher @done @timePeriod def reset() @done = false; @timePeriod = nil; end def watchToggling(aVariable, aTimeout=nil) oldState = aVariable; oldTime = 0; newTime = 0; timeout(aTimeout)do while(!@done) newState = aVariable; if(newState != oldState) if(newState == 1) # rising edge if(oldTime != 0) # there was already a rising edge before, # so we can calculate the period newTime = Time.now(); @timePeriod = newTime - oldTime; @done = true; else # if there was no previous rising edge, # set the time of this one oldTime = Time.now(); end end oldState = newState; end end end puts("Watcher: done.") end def isDone() return @done; end def getTimePeriod() return @timePeriod; end end 

在ruby中有什么方法可以通过引用传递吗? 如果没有,是否有替代方案可以解决这个问题?

Ruby是严格按值传递的,这意味着调用者范围内的引用是不可变的。 显然,它们在范围内是可变的,因为你可以分配它们,但它们不会改变调用者的范围。

 a = 'foo' def bar(b) b = 'bar' end bar(a) a # => 'foo' 

但请注意,即使引用不能, 对象也可以变异:

 a = 'foo' def bar(b) b << 'bar' # the only change: mutate the object instead of the reference b = 'baz' end bar(a) a # => 'foobar' 

如果你传递的对象也是不可变的,那么你无能为力。 Ruby中变异的唯一可能性是改变引用(通过赋值)或要求对象自己变异(通过调用它上面的方法)。

您可以从方法返回更新的值,并让调用者将其分配给引用:

 a = :foo def bar(b) :"#{a}bar" end c = bar(a) c # => :foobar 

或者你可以将不可变对象包装在一个可变对象中并改变那个可变包装器:

 a = [:foo] def bar(b) b[0] = :bar end bar(a) a # => [:bar] 

[这与上面的第二个例子非常相似。]

但如果你无法改变任何东西,那么你就会陷入困境。