如何在Ruby中就地“替换”数字对象

时间:2013-03-11 23:57:17

标签: ruby pass-by-reference

我正在尝试调整Ruby / Rails函数中的变量。许多其他语言的标准内容。

在c:

void change(int *io){
  *io = 1;
}

现在我们都知道Ruby是通过引用传递的(笑脸)。这段代码完美无缺:

def tester()
  value = 'dave'
  test_replace(value)
  p value.to_s;
end

def test_replace(ioValue)
  ioValue.replace 'test'  
end

输出为'test'。

所以问题是:固定数字没有替换方法。它们的传递方式与其他值不同。

所以我的问题是:我如何在Ruby中“io”一个“int”?

def tester()
  value = 10
  test_replace(value)
  p value.to_s;
end

def test_replace(ioValue)
  ioValue.replace 15  
end

哪个提出

  

未定义的方法`replace'为10:Fixnum

3 个答案:

答案 0 :(得分:5)

@Linuxios在他关于传递值的解释中是正确的,但他的解决方法非常尴尬。使用支持替换的SimpleDelegator包装fixnum非常容易:

class NumberBox < SimpleDelegator
  alias_method :replace, :__setobj__
  class <<self; alias_method :[], :new; end
end

def tester()
  value = NumberBox[10]
  test_replace(value)
  p value.to_s;
end

def test_replace(ioValue)
  ioValue.replace 15  
end

在上面value的行为与它所委托的对象完全相同,在初始化时建立(使用::newNumberBox::[]),但它也支持__setobj__方法及其别名replace,它将新对象绑定为委托人。

答案 1 :(得分:2)

实际上有两种方法可以做到这一点:

  1. 包裹物体
  2. 包裹数组
  3. 创建mutable-int代理对象
  4. 选项二很简单,我不会举一个例子。选项1看起来像这样:

    class IntRef < BasicObject
      def initialize(i)
        @int = i
      end
      def replace(v)
        @int = v
      end
      def method_missing(name, *args, &block)
        @int.send(name, *args, &block)
      end
    end
    

    或选项三:代理对象!

    class MutableInt < BasicObject
      def initialize(i)
        @int = i
      end
      def method_missing(name, *args, &block)
        v = @int.send(name, *args, &block)
        if(v.is_a?(::Fixnum))
          @int = v
          return self
        end
        v
      end
    end
    

    警告:您对此代理执行的任何操作 都会粘贴并更改对象。当心。

答案 2 :(得分:0)

  

现在我们都知道Ruby是通过引用传递的

相反,Ruby只是通过值传递。没有参考通过。与Java,Python等相同。