iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 4
0
自我挑戰組

Metaprogramming Ruby and Rails系列 第 4

Day 4 -- Inside the Object Model

"Where you learn surprising facts about objects, classes, and constants." from Metaprogramming Ruby

What is in an Object ?

class MyClass
  def my_method
    @v = 1
  end
end
obj = MyClass.new
obj.class                 # => MyClass

每個實例物件都會有它的實例變數,加上ㄧ個指向屬於CLASS的連結。

OBJECT = INSTANCE VARIABLES + a REFERENCE to a CLASS 

以下面的範例來說:這裡的 obj 是 MyClass 以 new 方法實例化的一個實例物件,而它的實例變數是 @v 以及指向 MyClass 的ㄧ個連結。
https://ithelp.ithome.com.tw/upload/images/20200919/20120868HPtCEGVu8p.png

Instance Variables

在 Ruby 的世界裡,實例變數(instance variable)是住在實例物件(instance object)裡面,而方法(method)卻是住在類別(class)。延續先前上面的範例,可用以下方法從實例物件來查詢它的實例變數:

obj.my_method
obj.instance_variables       # => [:@v]

有注意到是先呼叫 my_method() 而不直接呼叫 instance_variables 查詢實例變數。
原因是在 Ruby 程式設計裡,為了要讓都是屬於同一個 class 的 objects 都可以擁有自己不同的實例變數。
所以設計上物件(object)本身的類別(class)跟實例變數(instance variable)脫鉤。因此需要先呼叫 my_method() 方法 才能讓 @v=1 被定義。

class MyClass
  def my_method
    @v = 1
  end
def my_name(name='default')
    @name = name
  end
end
obj1 = MyClass.new
obj2 = MyClass.new
obj1.class                     # => MyClass

obj1.instance_variables        # => [], 實例變數還未定義

obj1.my_method                 # => 1, 呼叫my_method後,實例變數就被定義

obj1.instance_variables        # => [:@v]

obj1.my_name('Jean')           # => Jean

obj2.my_name                   # => default

obj2.my_name('Kevin')          # => Kevin

Methods

Objects 物件除了有實例變數外,也擁有在 class 內的許多方法可以使用。書中有介紹可查詢物件所擁有的方法:

obj1.class.superclass     # => Object

# 因為obj1從'Object'繼承了許多方法,所以回傳一堆obj1可使用的方法,
obj1.methods

# 利用regexp找出所有my開頭的方法
obj1.methods.grep(/my/)              # => [:my_method, :my_name]

# 可以找出MyClass的實例方法, 帶入false參數是要過濾掉從'Object'繼承的方法
obj1.class.instance_methods(false)   # => [:my_method, :my_name]

" An object's instance variables live in the object itself, and an object's methods live in the object's class. " from Metaprogramming Ruby

注意:雖然 實例方法 instance methods 是需要實例化的物件(例如: obj1)才能使用,但是實例方法是住在類別(例如: MyClass)裡面

重點回顧

  • 每個物件都有屬於它的實例變數,加上ㄧ個指向屬於CLASS的連結
  • 實例變數是住在實例物件裡,方法是住在類別

上一篇
Day 3 -- Open Class
下一篇
Day 5 -- The Truth About Classes
系列文
Metaprogramming Ruby and Rails33

尚未有邦友留言

立即登入留言