分配值时,属性不会更改?

时间:2012-03-18 17:54:04

标签: ruby-on-rails-3 activerecord ruby-1.9

我有点像Ruby,noob,还有一些基本的东西,我没有得到。我有这样的事情:

def my_method
    attr1 = 'new 1 value'
    attr2 = 'new 2 value'
    puts "#{attr1} - #{attr2}"
    puts "Should be same? #{to_s}"
end

def to_s
    "#{attr1} - #{attr2}"
end

当我打电话给my_method时,我得到:

new 1 value - new 2 value 
Should be same? old 1 value - old 2 value

咦?

3 个答案:

答案 0 :(得分:1)

这是因为在Ruby中

x = y

总是y生成的值分配给变量 x,而

obj.x = y

总是x= 消息发送到对象obj(由y生成的值)。

在Ruby中属性/属性实际上只是方法!因此,请尝试:

self.attr1 = 'new 1 value'
self.attr2 = 'new 2 value'

另一方面,y 可能是也可能不是方法调用(读取: property fetch)。这取决于范围内是否已存在变量y,因为变量 shadow 方法。这就是为attr1attr2to_s中工作而不需要加前缀的原因。

快乐的编码。

答案 1 :(得分:1)

范围attr1attr2是局部变量。

因此,当您致电to_s时,它会查找您已(或可能)在类范围内声明的attr_1attr_2。当你运行my_method而不是在较小的范围内创建一个新变量时,这些不会被覆盖。

请尝试使用@attr_1@attr_2

查看Local Variable Gotchas

答案 2 :(得分:1)

有两种方法可以做到这一点。一种是使用类范围的变量而不是局部变量:

class MyClass

    def my_method
        @attr1 = 'new 1 value'
        @attr2 = 'new 2 value'
        puts "#{@attr1} - #{@attr2}"
        puts "Should be same? #{self.to_s}"
    end

    def to_s
        "#{@attr1} - #{@attr2}"
    end
end

m = MyClass.new
m.my_method

输出:

new 1 value - new 2 value
Should be same? new 1 value - new 2 value

另一种方法是使用属性,你必须专门调用self上的方法:

class MyClass
    attr_accessor :attr1,:attr2

    def my_method
        self.attr1 = 'new 1 value'
        self.attr2 = 'new 2 value'
        puts "#{attr1} - #{attr2}"
        puts "Should be same? #{self.to_s}"
    end

    def to_s
        "#{attr1} - #{attr2}"
    end
end

m = MyClass.new
m.my_method

这具有相同的输出。