目录搜索
Ruby用户指南3、开始4、简单的例子5、字符串6、正则表达式7、数组8、回到那些简单的例子9、流程控制10、迭代器11、面向对象思维12、方法13、类14、继承15、重载方法16、访问控制17、单态方法18、模块19、过程对象20、变量21、全局变量22、实变量23、局部变量24、类常量25、异常处理:rescue26、异常处理:ensure27、存取器28、对象的初始化29、杂项RGSS入门教程1、什么是RGSS2、开始:最简单的脚本3、数据类型:数字4、数据类型:常量与变量5、数据类型:字符串6、控制语句:条件分歧语句7、控制语句:循环8、函数9、对象与类10、显示图片11、数组12、哈希表(关联数组)13、类14、数据库15、游戏对象16、精灵的管理17、窗口的管理18、活动指令19、场景类Programming Ruby的翻译Programming Ruby: The Pragmatic Programmer's Guide前言RoadmapRuby.new类,对象和变量容器Containers,块Blocks和迭代Iterators标准类型深入方法表达式Expressions异常,捕捉和抛出(已经开始,by jellen)模块基本输入输出线程和进程当遭遇挫折Ruby和它的世界Ruby和Web开发Ruby TkRuby 和微软的 Windows扩展RubyRuby语言 (by jellen)类和对象 (by jellen)Ruby安全反射Reflection内建类和方法标准库OO设计网络和Web库Windows支持内嵌文档交互式Ruby Shell支持Ruby参考手册Ruby首页卷首语Ruby的启动环境变量对象执行结束时的相关处理线程安全模型正则表达式字句构造程序变量和常数字面值操作符表达式控制结构方法调用类/方法的定义内部函数内部变量内部常数内部类/模块/异常类附加库Ruby变更记录ruby 1.6 特性ruby 1.7 特性Ruby术语集Ruby的运行平台pack模板字符串sprintf格式Marshal格式Ruby FAQRuby的陷阱
文字

变量和常数

  • 局部变量
  • 实例变量
  • 类变量
  • 全局变量
  • 伪变量
  • 常数
    • 引用常数的优先顺序

您可以通过区分Ruby变量名的首位字符来确定它是局部变量、实例变量、类变量、全局变量还是常数。通常情况下,变量名的第二位字符以后是数字、字母或下划线,但有的内部变量名比较特殊,如“'$'+1个符号”(请参考内部变量)。变量名长度只受内存大小的限制。

局部变量

例:

foobar

若标识符首位是小写字母或“_”,则该标识符就是局部变量或方法调用。在局部变量的作用域(类、模块、方法的定义部分)内,若对一个首位是小写字母的标识符进行首次赋值的话,也就意味着声明了一个属于该作用域的局部变量。若引用尚未被声明的标识符的话,就会被解释成一个无参数的方法调用。

局部变量的作用域起始于声明处,结束于该声明所在的块、方法定义、类/模块定义的结尾。随着块的消亡,局部变量也将寿终正寝(顶层局部变量则一直持续到程序终结),但也有例外。若块已经变成过程对象的话,则局部变量将一直持续到该过程对象终结为止。若多个过程对象引用同一个作用域的话,局部变量将被这些对象所共享。

# (A)的部分位于作用域之外
2.times {
  p defined?(v)    # (A)
  v = 1            # 从(开始声明)起
  p v              # 到(块的终结)是 v 的作用域
}

# => nil
     1
     nil           <- 请注意这里是 nil
     1

即使声明部分未被执行仍将有效。

v = 1 if false # 虽未赋值,但声明有效
p defined?(v)  # => "local-variable"
p v            # => nil

若使用了 -K 选项的话就可以使用日语标识符,日语标识符被当作局部变量处理。实际上,我们并不推荐您这样做。

实例变量

例:

@foobar

以@开始的变量是实例变量,它属于特定的对象。可以在类或子类的方法中引用实例变量。若引用尚未被初始化的实例变量的话,其值为nil。

类变量

例:

class Foo
  @@foo = 1
  def bar
    puts @@foo
  end
end

以@@开始的变量是类变量。在类的定义中定义类变量,可以在类的特殊方法、实例方法等处对类变量进行引用/赋值。

类变量与常数的区别如下。

  • 可以重复赋值(常数则会发出警告)
  • 不能在类的外部直接引用(在继承类中则可以引用/赋值)

类变量与类的实例变量的区别如下。

  • 可在子类中引用/赋值
  • 可在实例方法中引用/赋值

可以把类变量看作一种被类、子类以及它们的实例所共享的全局变量。

class Foo
  @@foo = 1
end
class Bar < Foo
  p @@foo += 1          # => 2
end
class Baz < Bar
  p @@foo += 1          # => 3
end

模块中定义的类变量(模块变量)被所有包含该模块的类所共享。

module Foo
  @@foo = 1
end
class Bar
  include Foo
  p @@foo += 1          # => 2
end
class Baz
  include Foo
  p @@foo += 1          # => 3
end

全局变量

例:

$foobar
$/

以$开始的变量是全局变量,可以在程序的任何地方加以引用(因此需要特别留意)。全局变量无需变量声明。引用尚未初始化的全局变量时,其值为 nil。

伪变量

除普通的变量之外,还有一种叫做伪变量的特殊变量。

self

当前方法的执行主体

nil

NilClass类的唯一实例

true

TrueClass类的唯一实例

false

FalseClass类的唯一实例。nil 和 false 表示“伪”。

__FILE__

当前源文件名

__LINE__

当前源文件中的行号

伪变量的值不可改变,若对伪变量赋值将引发语法错误。

常数

例:

FOOBAR

以大写字母([A-Z])开始的标识符是常数.常数的定义(和初始化)由赋值过程完成.不能在方法中对常数进行定义.若对已定义的常数进行赋值的话,会出现警告信息.若引用未定义的常数的话,则会引发NameError异常.

可以在下列地方引用常数,如,定义常数的类/模块的定义句(也包括方法正文以及嵌套类/模块的定义句)中,继承该类的子类中,以及包含模块的类/模块中等等.在类定义之外(顶层)定义的常数属于Object.

例:

class Foo
  FOO = 'FOO'       # 定义Foo类的常数FOO(Foo::FOO)
end

class Bar < Foo
  BAR = 'BAR'       # 定义Bar类的常数BAR(Bar::BAR)

  # 可直接引用父类的常数
  p FOO             # => "FOO"
  class Baz

    # 虽然嵌套类与该类间不存在继承关系
    # 但还是可以直接引用嵌套外部的常数
    p BAR           # => "BAR"
  end
end

另外,在类定义表达式生成类对象的同时,还会将类对象赋值给一个与该类同名的常数.从语法上讲,引用类名也就是引用该常数.

class C
end
p C    # => C

若想在外部访问类或模块中的常数时,要使用"::"操作符.若想准确地访问Object类中的常数(顶层的常数)时,也需要也使用"::"操作符,但操作符左边为空.另外,不能使用该操作符对常数进行赋值.

ruby 1.8 特性: 可以使用"::"对常数进行赋值.

例:

module M
  I = 35
  class C
  end
end
p M::I   #=> 35
p M::C   #=> M::C
p ::M    #=> M

M::NewConst = 777   # error--> parse error

引用常数的优先顺序

若在父类和嵌套外侧存在同名常数时,会先引用嵌套外侧的常数.也就是说,引用常数时会先搜索嵌套关系的外侧,然后才会按照继承关系向上搜索.

例:

class Foo
  CONST = 'Foo'
end

class Bar
  CONST = 'Bar'
  class Baz < Foo
    p CONST             # => "Bar"      外侧的常数
    # 此时,若不显式地指定父类中的常数的话,则无法找到该常数
    p Foo::CONST        # => "Foo"
  end
end

一般认为顶层常数定义并不是位于嵌套外侧,所以在搜索了继承关系之后才能找到它.可见顶层常数的优先度很低.

例:

class Foo
  CONST = 'Foo'
end

CONST = 'Object'

class Bar < Foo
  p CONST               # => "Foo"
end

# 若能明显看出是嵌套关系的话,按规则来说
# 首先搜索到的是Object的常数(位于嵌套外侧)
class Object
  class Bar < Foo
    p CONST             # => "Object"
  end
end

若对与父类常数同名的常数进行赋值的话,则意味着在该类中定义一个新常数,而并不会对父类常数进行赋值.

例:

class Foo
  CONST = 'Foo'
end
class Bar < Foo
  p CONST               # => "Foo"
  CONST = 'Bar'         # *定义*Bar的常数CONST
  p CONST               # => "Bar"  (Foo::CONST 被屏蔽了)
  p Foo::CONST          # => "Foo"  (若使用:: 的话就可以了)
end

上一篇:下一篇: