今天尝试了下对常量赋值,发现也没有报错,只是给出了警告。难道可以对常量进行赋值么???
可以 Ruby 常量不是 C 常量 凡是内存里的数据 没有不可赋值的 Ruby 已经给出了警告(我记得好像有个什么选项可以彻底阻止的,不过我也没用过 不记得了)但是如果用的是 const_set 那就没有警告了
[jasl@Jasl-rMBP:~/workspace/ruby]$ pry
[1] pry(main)> class A
[1] pry(main)* class<< self
[1] pry(main)* attr_accessor :foo
[1] pry(main)* end
[1] pry(main)* end
=> nil
[2] pry(main)> A.foo
=> nil
[3] pry(main)> A.foo = "bar"
=> "bar"
[4] pry(main)> A.foo
=> "bar"
class Test
class << self
attr_accessor :count
end
def add
@@count += 1
puts @@count
end
end
test = Test.new
Test.count =5
puts Test.count
test.add
这样定义了之后在实例方法中操作类变量就出错。
class Test
class << self
attr_accessor :count
end
def add
@count += 1
puts @count
end
end
test = Test.new
Test.count =5
puts Test.count
test.add
count 定义为实例变量,但是 add 中也访问不了
class Test
attr_writer :count
def initialize
@count = 2
end
def add
@count += 1
puts @count
end
end
test = Test.new
test.count =5
#puts Test.count
test.add
class Test
class << self
attr_accessor :count
end
def add
self.class.class_exec do
@count += 1
puts @count
end
end
end
test = Test.new
Test.count =5
puts Test.count
test.add
class Test
class << self
attr_accessor :count
end
end
这个 count 是 Test 的 Class_Instance_Variable,而你在 17 楼写的 add 方法是 Test 的实例的方法,test 是 Test 的实例,count 是 Class_Instance 的变量,你怎么可能在一个实例中直接操作另一个实例的变量而不用 setter,getter 呢?
#28 楼 @xautjzd 这里所说的 Class_Instance 并非平时常见的实例。 Ruby 中 每一个类本身也是 Class 的 实例。 所以上述中的 Test 是 Class 类的一个实例,上述创建的 count 变量实际是 Test 这个 Class 实例自身的变量,地位等同@@count(只是@@count 能被继承和 Test 的真正实例直接访问)。而你的 add 方法的 self 指向的是 Test 的真正实例,如你写的 test。add 能直接操作的只是 Test 的实例变量,而不能直接操作上述中的 count。
Ruby 有所谓域门,在 class 关键字直接范围下,self 指代 class 自身,而一旦进入 def 关键字下,那 self 就指代之后会创建的实例对象了。
class Test
@var1 #这个是Class类的实例Test的变量
def some_func
@var2 #这个是Test.new创建的实例的变量
end
end
指代不同,当然不能直接操作了。我不一定能表述得清楚,具体可以去看《Ruby 元编程》。Good luck.