2016-09-13 69 views
2

PHP我写:Ruby类变量初始值

Class Test{ 
    public $a=100; 
} 

$a=new Test(); 
echo $a->a; //prints 100 

它打印100,但在红宝石当我写:

class Test 
    @a=100 
    attr_accessor :a 
end 

a=Test.new 
puts a.a #=> prints nil 

a为零并且它打印nil。为什么?

回答

2

你混合事情有点。

你用@a = 100定义的是类实例变量

你打算用attr_accessor :a访问的是实例变量@a。实例变量的使用的

实施例:

class A 
    def initialize a 
    @a = a 
    end 
    attr_accessor :a 
end 

instance = A.new(2) 
#=> 2 
instance.instance_variables 
#=> [:@a] 
instance.a 
#=> 2 

类的实例变量的使用的示例:

class A 
    @a = 1 
    class << self 
    attr_accessor :a 
    end 
end 

A.a 
#=> nil 
A.a = 2 
#=> 2 
A.a 
#=> 2 
instance = A.new 
instance.class.a # access instance's class instance variable 
#=> 2 
+0

谢谢你的解释。那么,我可以说,继承类中的'a'可以用'100'值访问吗? – emj

+2

'cattr_accessor'是导轨的一部分,不适合这个问题(无'rails'标签) – sokkyoku

+0

@sokkyoku thx,编辑 –

1

试试这个:

class Test 
    attr_accessor :a 

    def initialize 
    @a = 100 
    end 
end 

a = Test.new 
puts a.a 
+2

这不是对“为什么?”这个问题的解释/回答。 –

1

发生这种情况的原因是,这条线:

@a = 100 

被分配到一个实例变量,但不是你认为的那个。它被分配到Test.a,(试验是的Class一个实例),而不是属于Test

反过来,这条线的每个实例的一个实例变量a

attr_accessor :a 

被声明一个访问器,以所谓a实例变量(可通过Test任何实例)

因此,你应该要么有

class Test 
    @a = 100 
    class << self 
     attr_accessor :a 
    end 
end 
puts Test.a #=> will print 100 

class Test 
    def initialize 
     @a = 100 
    end 
    attr_accessor :a 
end 
a = Test.new 
puts a.a #=> will print 100 

它还是依靠如果你只是想一个类常量,如果你想在每个实例的默认值的属性。后者是您的PHP代码的直接翻译。

+1

说这条线*是*分配一个实例变量会更准确(并且最终更有用)。之后,所有,它是一个赋值('='),它是一个实例变量('@')。只是实例不是OP认为的实例。它*是一个实例变量,但是对于*错误*实例。 –

+0

好点,修改我的答案 – sokkyoku

2

实例变量属于对象(又名实例),这就是为什么他们被称为“实例变量”毕竟。

有两个对象的位置:Test,这是Class一个实例,a,这是Test一个实例。两者都像对象一样是对象。两者都可以像其他任何对象一样拥有实例变量。

两者都有一个名为@a的实例变量。Foo@a已初始化为100a@a尚未初始化,单元化实例变量计算为nil

所以,你的问题是,你正在混淆你正在看哪个实例。实例变量总是在self中查找,而在类定义体内部,self是正在定义的类。

这听起来可能听起来很迂腐,但我发现,理解Ruby其实是比简单得多人们有时想让你相信,最终会帮助你。