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

标签 ruby parameter-passing pass-by-reference pass-by-value pass-by-pointer

目前我正在用 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

或者您可以将不可变对象(immutable对象)包装在可变对象中并改变该可变包装器:

a = [:foo]

def bar(b)
  b[0] = :bar
end

bar(a)

a
# => [:bar]

[这和上面的第二个例子真的是一回事。]

但如果你不能改变任何东西,那么你就被困住了。

关于ruby - 如何在 Ruby 中通过引用传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39203911/

相关文章:

ruby-on-rails - Cocoon - 用于查找或创建的参数数量错误(1 代表 0):belongs_to

ruby-on-rails - Ruby 遍历一个变量,除非它是 nil

ruby - 错误 : "fatal: I don' t handle protocol `` git` when using bundle install

Javascript:如何将变量的值(而不是引用)传递给函数?

ruby - 如何在 watir-webdriver 中查看应用于 HTML 元素的 CSS 样式?

Java 按引用传递和编译器优化

javascript - 如何将 AngularJS ng-repeat 变量传递给 Javascript 点击事件

java - java 中传递给静态函数的参数的更改

c - 通过引用传递 int/char 数组的错误/警告

c++ - 重载运算符 << 返回 ostream&