學習ruby類相關的文法遇到的關於類相關變數的一點小體會。
ruby很靈活,文法看似很隨意,比如看下下面的代碼
class Foo
attr_accessor :name
def initialize
@name = '小明'
end
def say
puts @name
puts self.name
puts name
end
end
Foo.new.say
執行這些代碼將得到如下輸出:
小明
小明
小明
initialize是建構函式,在
Foo.new
的時候自動執行,
@name
是執行個體變數,那麼在
say
方法中
puts @name
很好理解,就是列印執行個體變數
@name
。
puts self.name
怎麼理解呢?
首先,self代表什嗎?它跟php的
$this
意義差不多,代表的是這個執行個體,在類方法中使用。
那
self.name
是表示一個類變數嗎?不是的。
其實這是一個方法,若要寫出來則是:
def name
return @name
end
很神奇不是嗎?那如果你奇怪這個方法哪來的,那你應該注意到第二行的一句代碼
attr_accessor :name
是的,
attr_accessor :name
這也是一個方法,等於是
attr_accessor(:name)
因為在ruby中括弧是可以省略的,初學時可能閱讀代碼比較彆扭。
:name
是一個符號,
attr_accessor
方法根據它來決定為
@name
執行個體變數建立
name
和
name=
等相關方法,即可實現在類外部通過運算式直接對執行個體變數賦值,如:
foo = Foo.new
foo.name = '小李' #name和=之間的空格會忽略,ruby忽略空格
puts foo.name
self.name
說明白了,那麼再來看看最後一項
puts name
這是什麼,這裡的
name
應當怎麼理解。
其實很好理解,因為ruby中調用方法可以省略括弧,所以當你看到一個變數時,它可能是局部變數,也可能是方法,優先順序嘛,當然是先局部變數。
我們看到
say
方法中沒有定義局部變數,所以這裡的
name
就當是方法了,等於是
name()
其實加上關鍵字self也一樣
self.name()
。
越來越感慨ruby的靈活多變了,當然我還是覺得應當遵循一定的規範,不然你寫的代碼別人可能根本無法看懂。
我來寫項目的話,在類方法內部我肯定是直接通過
@name
操作,而不會用
self.name
或
name
去做,你覺得呢?
以@開始的變數是【執行個體變數】,執行個體變數屬於特定的對象。
class Person
def initialize(name, gender, age)
@name = name
@gender = gender
@age = age
end
end
上面的例子中,@name, @gender,@age都是執行個體變數。可以在類或子類的方法中引用執行個體變數。若引用尚未被初始化的執行個體變數的話,其值為nil。
【類變數】被一個類的所有執行個體對象共用,也可以被類方法訪問到。類變數名以‘@@’,開始,例如‘@@number’。和全域變數,執行個體變數不同,類變數在使用前必須初始化:
class Person
@@number = 0 #使用前必須有初值
def initialize(name, gender, age)
@name = name
@gender = gender
@age = age
@@number += 1
end
end
類變數是私人的,在類外無法直接存取,你只能通過執行個體方法和類方法去訪問它。