在users/index視圖中,僅僅通過一句代碼就能自動產生分頁連結:
<%= will_paginate %>
我並未告訴它改對哪個目標數組進行分頁,然而它能智能定位到
@users
變數。
太神奇了,忍不住好奇,看了下代碼
def will_paginate(collection = nil, options = {})
.
.
.
collection ||= infer_collection_from_controller
.
.
end
發現集合對象會通過
infer_collection_from_controller
來擷取預設值,繼續挖掘代碼。
def infer_collection_from_controller
collection_name = "@#{controller.controller_name}"
collection = instance_variable_get(collection_name)
raise ArgumentError, "The #{collection_name} variable appears to be empty. Did you " +
"forget to pass the collection object for will_paginate?" if collection.nil?
collection
end
發現它構造了一個以controller名字同名的變數名
@users
,然後通過
instance_variable_get
從controller執行個體中找到名為
@users
的變數並返回。
總結:通過
instance_variable_get
我們可以在調用該方法的上下文環境中尋找執行個體變數?他日深入學習下。
補充
ruby 1.8 特性
取得並返回對象的執行個體變數的值.
可以使用字串或者Symbol來向var指定執行個體變數名.
若執行個體變數尚未定義,則返回nil.
class Foo
def initialize
@foo = 1
end
end
obj = Foo.new
p obj.instance_variable_get("@foo") # => 1
p obj.instance_variable_get(:@foo) # => 1
p obj.instance_variable_get(:@bar) # => nil
instance_variable_set(var, val)
ruby 1.8 特性
將val的值賦值給對象的執行個體變數並返回該值.
可以使用字串或Symbol來向var設定執行個體變數名.
若執行個體變數尚未定義,則重新定義.
obj = Object.new
p obj.instance_variable_set("@foo", 1) # => 1
p obj.instance_variable_set(:@foo, 2) # => 2
p obj.instance_variable_get(:@foo) # => 2