class A
@i = "hi"
def say
puts "#{@i}"
end
end
ins = A.new
ins.say
class A
@i = "hi"
puts "此时self是#{self}"
def say
puts "此时self是#{self}, A的一个实例"
puts "#{@i}"
end
end
ins = A.new
ins.say
两个@i
不是同一个东西,def
会打开新的作用域。
def
里面的@i
好理解,就是 A 的每一个实例的实例变量。
def
外面的@i
,首先要知道 A 是 Class 的一个实例
ins.class # A
A.class # Class
一个实例自然可以拥有自己的实例变量
#6 楼 @uestc_bird 楼上几位都说的很好了。补充一点便于你理解他们的所说观点:
class A
@i = "hi"
def say
puts "#{@i}"
end
end
# 上下两中写法几乎一样
A = Class.new do
@i = "hi"
def say
puts "#{@i}"
end
end
:plus1 :clap :sm
再补充一点
class A
@i = "hi"
def self.say
puts "#{@i}"
end
end
A.say # 'hi'
比较容易理解一点的方法就是你要知道实例变量是定义在 self 上的,所以想搞清楚这两个@i有什么区别首先要知道这两个地方的 self 有什么区别。尝试如下:
class A
@i = "hi"
puts "First place: self is #{self}, @i is #{@i}."
# 实例方法
def say
puts "Second place: self is #{self}, @i is #{@i}."
end
# 类方法,类似于java的static方法
def self.say
puts "Third place: self is #{self}, @i is #{@i}."
end
end
a = A.new
a.say
A.say
结果如下:
First place: self is A, @i is hi.
=> :say
[68] pry(main)>
[69] pry(main)> a = A.new
=> #<A:0x0000000790cd90>
[70] pry(main)> a.say
Second place: self is #<A:0x0000000790cd90>, @i is .
=> nil
[71] pry(main)> A.say
Third place: self is A, @i is hi.
=> nil
这里可以很清楚的看到第一个@i定义的时候 self 是 A,所以第一个实例变量 i 是定义在 A 上的;第二个地方 self 是# 也就是 A 的一个匿名类(可以理解为实例 a),这个时候调用定义在该匿名类(可以理解为实例 a)上的实例变量 i,明显未定义过,所以为 nil;第三个地方 self 是 A,调用定义在 A 上的实例变量 i,故而有值。
除了 self 的概念,ruby 中还有当前类的概念,掌握了这两个概念,这些问题都可以迎刃而解。
最后,推荐你看一下 ruby 元编程。