ruby之变量

 

 ruby的变量有局部变量,全局变量,实例变量,类变量,常量。

1、局部变量

1). 命名规则:以小写字母或者下划线开头;

2). Ruby中的方法调用也是以小写字母或下划线开头,而且调用的方法如果没有参数,则可以省略方法后的括号;

3). 局部变量的定义:类、模块、方法的内部,当我们对一个以小写字母开头的变量进行赋值时,就声明了一个局部变量;离开范围局部变量消失;

4). 允许定义顶层局部变量,但在类、方法、模块定义内仍无法访问该变量;

5). 局部变量不可以在内部类、子类中访问;类中的方法不可以访问该类中定义的局部变量(平级);;

6). 在声明局部变量的类、模块、方法内,局部变量从声明该变量处开始生效,随类、方法、模块的定义结束而结束;

 

  局部变量以一个小写字母开头或下划线开头

  局部变量有局部作用域限制(比如一个block内),它的作用域起始于声明处,结束于该声明所在的块、方法定义、类/模块定义的结尾。大家在写代码时经常这样写:

   irb(main):001:0> i=123    ---------- 这里的i就是局部变量

   =>123

   irb(main):002:0> s="hi"   ---------- 这里的s就是局部变量          

   =>"hi"
 ruby的变量是动态变量,某个变量在前一刻是数字型,在后一刻可以是字符型:

   irb(main):003:0> x=321

   =>321

   irb(main):004:0> x="hello" 

   =>"hello"

 ruby是动态变量,但却是强类型,例如字符和数字不能直接相加:

  irb(main):005:0> x=10

  =>10

  irb(main):006:0> y="hi"

  =>"hi"

  irb(main):007:0> x+y

  TypeError: String can't be coerced into Fixnum

    from(irb):7:in '+'

    from(irb):7
    from : 0

 必须手工进行转换: irb(main):008:0>  x.to_s + y

  => "10hi"


2、全局变量

1). 命名规则:以“$”开头;可以在任何地方访问;

2). 通常应避免使用全局变量,因为它的使用会引起各模块间的高耦合。

3). 全局变量无需声明,引用尚未初始化的全局变量,其值为nil;

4). 定义:可以在类、模块、方法的定义中进行全局变量的定义;

5). 全局变量的作用范围是从全局变量的定义语句开始,直到程序结束;

6). 动态语言的特征:当定义一个方法时,该方法根本不会被解释,只有真正调用该方法时,该方法才会被解释。

7). Ruby提供了一系列常用的全局变量;如;错误为止,解释器进程ID;

 

   ruby的全局变量以$开头,例如:  $x   $y。全局变量可以在程序的任何地方加以引用。全局变量无需变量声明。引用尚未初始化的全局变量时,其值为nil

    ruby有内置的全局变量,应该是从perl哪里抄来的,例如 $!记录最近一次产生的错误,$. 表示行号等。良好的编程实际,是不使用全局变量,他们危险而难以跟踪。

 

3、实例变量

1). 命名规则:以“@”开头;每个实例变量都是在第一次出现时动态加入对象;

2). 实例变量通常在方法中定义;

    当在方法中声明实例变量时,该实例变量事实上属于该方法所在的类,而不是该方法;

    虽然实例变量是属于类的,但大部分时候我们都是在该类的方法里定义实例变量;

3). Java在创建对象时一次为该对象的所有实例变量都分配了相应的内存空间;

  Ruby语言里的对象完全是动态的,创建对象时该对象没有任何实例变量,直到执行到为实例变量定义时,该对象才动态增加该实例变量;

4). 生存范围:与该类对象的生存范围相同,只要该类对象存在,则该对象里的实例变量将一直存在;

    但局部变量则会随着方法的消亡而消亡(除非使用闭包);

5). 实例变量的访问范围总是:private,即在类定义内对实例变量的赋值和读取没有限制;在类外访问实例变量时,则可以通过方法来访问;

6). 属性定义:1.用实例变量;2.用Module的方法(四个方法:attr,attr_reader,attr_writer,attr_accessor;示例:attr:color,true;);

7). 在模块中定义实例变量,目的是将该实例变量混入其他类中;(模块是无法创建实例的);

8). 类范围内定义的实例变量是Class对象的实例变量;

9). 实例变量永远都不能暴露为public,只能通过类方法(类名.方法名)暴露;

 

  ruby的实例变量以@开头,是指实例化后的对象,才绑定的变量。实例变量属于特定的对象。例如:

irb(main):016:0> class Myclass
irb(main):017:0>   def initialize(name,gender,age)
irb(main):018:0>      @name=name

irb(main):019:0>      @gender=gender
irb(main):020:2>      @age=age
irb(main):021:0>   end
irb(main):022:0> end
=> nil    ---------------@name @gender@age都是实例变量。可以在类或子类的方法中引用实例变量。若引用尚未被初始化的实例变量的话,其值为nil。

irb(main):023:0> x=Myclass.new("john")
=> #<Myclass:0x7f2e15a7dad8 @name="john">

Myclass类,他的构造器接收一个name参数,然后把该参数赋值给实例变量@name。

x是Myclass的实例,她拥有实例变量@name。

只有在类被实例化时,实例变量才产生和存在。但是,实例对象并不能直接访问实例变量:

irb(main):022:0> x.@name
SyntaxError: compile error
(irb):22: syntax error, unexpected tIVAR
        from (irb):22
        from :0

  这样是错误的。必须在;类里面,定义get方法,来访问实例变量:

irb(main):023:0> class Myclass
irb(main):024:1>   def name
irb(main):025:2>     @name
irb(main):026:2>   end
irb(main):027:1> end
=> nil

irb(main):028:0> x.name
=> "john"

  当然,也可以定义set方法,来设置实例变量:

irb(main):029:0> class Myclass
irb(main):030:1>   def name=(value)
irb(main):031:2>     @name=value
irb(main):032:2>   end
irb(main):033:1> end
=> nil

irb(main):034:0> x.name="jean"
=> "jean"

irb(main):035:0> x.name
=> "jean"

  这个set和get,可以通过ruby的元编程来实现,例如:

irb(main):036:0> class Myclass
irb(main):037:1>   attr_accessor :age
irb(main):038:1> end
=> nil

irb(main):039:0> x.age=20
=> 20

irb(main):040:0> x.age
=> 20

  只要设置attr_accessor就够了,他会对@age这个实例变量,创建set和get方法。

irb(main):041:0> x
=> #<Myclass:0x7f2e15a7dad8 @name="jean", @age=20>

对应的还有attr_reader只设置get方法,attr_writer只设置set方法。

4、类变量

1. 命名规则:以“@@”开头;从第一次开始赋值的地方开始生效;

2. 定义:可以在类、模块、方法的定义中定义类变量;(在方法中定义的变量只有在该方法被调用后,该类变量才会生效)

3. 访问:可以在类中的特殊方法、实例方法等处对类变量进行引用和赋值;

4. 类变量必须先定义,然后才可以使用,否则异常;

5. 类变量的特殊性:一个类、其子类、它们的实例:的同名类变量共享了同一块内存区域(都引用了同一个变量);

6. 可以在模块中定义类变量,所有混入该模块的类,共享该模块中定义的类变量;仍然共享内存区域;

7. 类变量与常量:

  *类变量可以重复赋值;常量重复赋值时发出警告(不是错误);

  *类变量默认是protected的,不能在类外部直接引用;(可在继承类中以用或赋值);

    类变量与实例变量:

  *在类范围内定义的类变量,可以在该类的方法中访问;而实例变量则不行;

  *类变量可在子类中引用或赋值,但实例变量可在类范围内直接引用或赋值;

 

   ruby的类变量以@@开头,例如在类里申明的@@x @@y 等,一般很少使用。

类变量在类的定义中定义,可以在类的特殊方法、实例方法等处对类变量进行赋值和引用。类变量被类,类的子类和他们的实例对象共享。

class Person

       @@number = 0 #使用前必须有初值

def initialize(name, gender, age)

  @name = name

  @gender = gender

@age = age

@@number += 1

end

end

    类变量是私有的,在类外无法直接访问,你只能通过实例方法和类方法去访问它。可以把类变量看作一种被类、子类以及它们的实例所共享的全局变量。

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

    module TestModule

        @@foo = 10

    end

    class Klass

        include Foo

        p @@foo += 1          # => 11

    end

    class Base

       include Foo

        p @@foo += 2          # => 12

    end

 

5、常量

   ruby的常量以大写字母开头,常数的定义和初始化由赋值过程完成。

     irb(main):048:0>Pi=3.14            ----------Pi就是一个常量

     =>3.14

  然而,ruby的常量是可以改变的。若对已定义的常数进行赋值的话,会出现警告信息:

irb(main):049:0> Pi=3.15
(irb):49: warning: already initialized constant Pi
=> 3.15

irb(main):050:0> Pi
=> 3.15

  尽管触发警告,但常量的确被改变了。

 注意:1)若引用未定义的常数会引发NameError异常。

       2)常量可以定义在类和模块中,不能定义在方法中

通常在类里设置常量:

irb(main):051:0> class Myclass
irb(main):052:1>   Pi=3.1415
irb(main):053:1> end
=> 3.1415

 3)若想在外部访问类或模块中的常数时,要使用“::”操作符. 

  从类的外部访问这个常量:irb(main):055:0>Myclass::Pi

                         =>3.1415

  模块也一样,例如访问ruby内置的Math模块的PI常量: irb(main):056:0>Math::PI

                                                  =>3.14159265358979

  4)在类定义表达式生成类对象的同时,还会将类对象赋值给一个与该类同名的常数,引用类名也就是引用该常数。

     class Test

     end

 

     p Test.class         #Class

     p Test               #test

 若想访问Object类中的常数(顶层的常数)时,也需要也使用"::"操作符,但操作符左边为空

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值