A.5 变量和它的作用域---(1)

A.5 变量和它的作用域---(1)

常量一般要求其值不用再改变了。这样不会运动的量不会产生丰富的且富于变化的时空效应。这里空间指它占用的内存空间,时间指它的值的变化特性。显然我们为了描述世界或着构造概念的时候,希望有些量在占用了内存空间后可以是随着时间来变化的,这时候我们需要定义变量。给该变量占用的内存区域取个名字就是该变量的名称,而该变量随着时间而变化的作用范围就是变量的作用域(因为你的程序将用时间来运行)。在内存空间里面的内容就是变量的值。
    根据变量所在的作用域——即它的作用范围,可以将变量划分为:局部变量、全局变量、实例变量、类变量和特殊变量。
    下面我们一一来理解这些变量:
1、局部变量
    局部变量名以小写字母或下划线开头。
    局部变量可以定义在:顶层对象、类、模块以及方法之中。也就是说:局部变量的作用域可以在顶层对象、类、模块以及方法之中。随着变量离开这些作用域,局部变量自然消失。当然你应该注意顶层对象的作用域是整个程序,程序结束时,在其中的局部变量消失。不过,只要局部变量没有分别定义在方法、类(包括其子类)、模块中(即各自的作用域中),你就无法访问到它,这时你如果没有直接使用到该变量时,程序运行可能暂时不会暴露其错误,但当你错误地认为该变量起作用的时候,NameError错误就会产生。

local = 110

def ok
 puts local
end

class A
  #puts local
  def ok
   puts local
  end
end
 
module B
  #puts local
  def ok
   puts local
  end
end

puts defined?local

    上面这个程序,当你试着去掉注释或调用这些方法而错误地想直接使用变量local时,错误就发生了。
    要注意的是:局部变量要定义后才可以使用。
    另外局部变量在过程块中的语法后面章节中叙述。

[Copy to clipboard] [ - ]
看来效果还不错,大家都没啥问题。
那就继续~~
感谢.....
补充一个,新手经常犯难的地方
class A
@b=1
end
如例,在类中定义了一个实例变量。我们称“类的实例变量”(注意,平时所用的实例变量是是对象的实例变量),要想访问到它,我们可以这么办,但是为什么,请大家先思考,后期给上原理分析:

class A
 class <<self
   attr_reader :b
 end
end

puts A.b  --> 1
对上面的原因进行分析
class <<self 表示创建一个类,与self这个类关联,self还是表示自己,那也就是说为自己类建了一个虚拟类。
Ruby代码的定义也是可以执行的。也是有执行环境的。
因为class定义时的上下文环境实际上是Class(在定义体中puts self.class就知道了),而Class类的父类是Module,因此在定义体中就可以调用祖先类--Module中的方法 attr_reader,用它定义了对@b的访问,使得我们可以读出@b的值。
那么有人会想到。如果在class A中定义一个方法,可以返回@b的值嘛?答案是不可以的,你可以试试,因为类的实例变量是定义在metaclass中的,所以我们要在metaclass中定议访问函数。如果你理解到这,基本上明白ruby的类的内部机制了
嗯,谢谢wtb,学习了
如果你理解到这,基本上明白ruby的类的内部机制了

晕了
引用:
原帖由 jluxzp 于 2008-7-25 14:26 发表
如果你理解到这,基本上明白ruby的类的内部机制了

晕了
看了黑马兄的解释,我是这样理解的,不知道对不对:
class A
class <<self
 attr_reader :b
end
end
就这段代码而言,A既是一个class,又是Class这个class的实例;self出现的上下文决定它指代的是A;所以上面这段代码为Class这个class的实例A加了一个attr_reader。而调用
puts A.b
的时候,A代表的也是Class这个class的实例。
关于class <<我不太懂。但我把class <<后的标识(如self或者别的什么)理解为某个类的实例(如果它本身就是一个类,那就是Class的实例),然后class <<的作用就相当于打开这个类,追加(只针对这个实例的)定义。