如何正確實(shí)現(xiàn)Ruby創(chuàng)建可參數(shù)化類
Ruby語(yǔ)言在實(shí)際使用中會(huì)創(chuàng)建許多類,來(lái)滿足我們的整體編程需求。對(duì)于初學(xué)者來(lái)說(shuō),我們必須熟練地掌握創(chuàng)建類的方法,比如Ruby創(chuàng)建可參數(shù)化類等等。#t#
如果我們要?jiǎng)?chuàng)建很多類,這些類只有類成員的初始值不同,我們很容易想起:
- class IntelligentLife # Wrong
way to do this! - @@home_planet = nil
- def IntelligentLife.home_planet
- @@home_planet
- end
- def IntelligentLife.home_planet=(x)
- @@home_planet = x
- end
- #...
- end
- class Terran < IntelligentLife
- @@home_planet = "Earth"
- #...
- end
- class Martian < IntelligentLife
- @@home_planet = "Mars"
- #...
- end
這種Ruby創(chuàng)建可參數(shù)化類方式是錯(cuò)誤的,實(shí)際上Ruby中的類成員不僅在這個(gè)類中被所有對(duì)象共享,實(shí)際上會(huì)被整個(gè)繼承體系共享,所以我們調(diào)用Terran.home_planet,會(huì)輸出“Mars”,而我們期望的是Earth一個(gè)可行的方法:
我們可以通過class_eval在運(yùn)行時(shí)延遲求值來(lái)達(dá)到目標(biāo):
- class IntelligentLife
- def IntelligentLife.home_planet
- class_eval("@@home_planet")
- end
- def IntelligentLife.home_planet=(x)
- class_eval("@@home_planet = #{x}")
- end
- #...
- end
- class Terran < IntelligentLife
- @@home_planet = "Earth"
- #...
- end
- class Martian < IntelligentLife
- @@home_planet = "Mars"
- #...
- end
- puts Terran.home_planet # Earth
- puts Martian.home_planet # Mars
最好的Ruby創(chuàng)建可參數(shù)化類方法:
我們不使用類變量,而是使用類實(shí)例變量:
- class IntelligentLife
- class << self
- attr_accessor :home_planet
- end
- #...
- end
- class Terran < IntelligentLife
- self.home_planet = "Earth"
- #...
- end
- class Martian < IntelligentLife
- self.home_planet = "Mars"
- #...
- end
- puts Terran.home_planet # Earth
- puts Martian.home_planet # Mars