ruby中實例變量、類變量等等的區別和聯系
ruby的變量有局部變量,全局變量,實例變量,類變量,常量。
1、局部變量
局部變量以一個小寫字母開頭或下劃線開頭
局部變量有局部作用域限制(比如一個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、全局變量
ruby的全局變量以$開頭,例如: $x $y。全局變量可以在程序的任何地方加以引用。全局變量無需變量聲明。引用尚未初始化的全局變量時,其值為nil
ruby有內置的全局變量,應該是從perl哪里抄來的,例如 $!記錄最近一次產生的錯誤,$. 表示行號等。良好的編程實際,是不使用全局變量,他們危險而難以跟蹤。
3、實例變量
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 Myclassirb(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 Myclassirb(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 Myclassirb(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、類變量
ruby的類變量以@@開頭,例如在類里申明的@@x @@y 等,一般很少使用。
類變量在類的定義中定義,可以在類的特殊方法、實例方法等處對類變量進行賦值和引用。類變量被類,類的子類和他們的實例對象共享。
class Person
@@number = 0 #使用前必須有初值
def initialize(name, gender, age)
@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類中的常數(頂層的常數)時,也需要也使用"::"操作符,但操作符左邊為空。