Categories
Programming Ruby

一些 Ruby Dynamic Features 記事 (1) OOP

趁過年把 The Ruby Way 拿起來讀一讀,大部頭一本沒辦法從頭念到尾,就挑了最重要的第11章( OOP and Dynamic Features in Ruby) 來念。這個主題值得閱讀的還有 Ruby for Rails 第13章(Ruby dynamics) 跟最近出的 Advanced Rails 一書第1章(Foundational Techniques),因此這幾篇文我還會修修改改就是了。

A “Fancy” Constructor

class Foo
 attr_accessor :a,:b
 def initialize(&block) 
  instance_eval &block
 end
end

於是可以傳入 block 來使用建構式

bar = Foo.new do
 self.a = 1
 self.b = 2
end

class instance variables

因為 Ruby 的 class 也是物件(即 Object 的 instance ),所以除了 class variable 跟 instance variable 之外,還有種變數叫做 class instance variables (即 class Class 的 instance variable 叫做 the class instance variable)。

class Foo
@@var =1 # 這是 class variable
@var = 2 # 這是 class instance variable
attr_accessor :var #這將定義出 instance variable

class << self
 attr_accessor :var2 #這將定義出 class instance variable
end

 def initialize
  @var,@var2 = 4,5 # 這是 instance variable
 end

 def mymethod1
  puts @@var # 1 這是 class variable
  puts @var # 4  這是 instance variable
  puts @var2 # 5  這是 instance variable
 end

 def Foo.classmethod
  puts @@var # 1 這是 class variable
  puts @var # 2 這是 class instance variable
  Foo.var2 = 6 # 這也是 class instance variable
end
end

class BarOne < Foo
  self.var2 = 7
end

class BarTwo < Foo
  self.var2 = 8
end

Foo.classmethod
puts Foo.var2 # 6
puts BarOne.var2 #7
puts BarTwo.var2 #8

class instance variable 跟 class variable 最大的不同在於,class variable 在整個 class 繼承體系都是指同一個,而 class instance variable 則是各個 class 皆不同,因為如此 class instance variable 很多時候比 class variable 好用,像是參數化的 classes。

const_get

const_get 可以從名稱拿到常數:

 str = "PI"
 Math.const_get(str) # 得到 Math::PI

而在 Ruby 裡面所有的 class 也都是 Object 裡的常數,所以要由名稱拿到 class 是這樣寫 :

 classname = "Array"
 klass = Object.const_get(classname) # 拿到 Array
 arr = klass.new(4,1) # [1,1,1,1]

binding

利用 eval 跟內建的 Binding 物件,我們可以把當下的 context 傳到函數裡面,建立出與本來的 scope 一樣的執行環境(因此這裡可以存取到 local variables )。

def print_var( var_name, binding )
 eval "puts #{var_name}", binding
end

foobar = 10
print_var( 'foobar' , binding )

2 replies on “一些 Ruby Dynamic Features 記事 (1) OOP”

请教一下:在你例子中第三行定义的 这个var变量
attr_accessor :var #這將定義出 instance variable
和在
def initialize
@var,@var2 = 4,5 # 這是 instance variable
end
中定义的@var,是否是同一个变量?

Leave a Reply