"Where you learn surprising facts about objects, classes, and constants." from Metaprogramming Ruby
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 的ㄧ個連結。
在 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
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)裡面