ruby之instance_variable_get,函数不指定参数自动寻找实例变量

作者:袖梨 2022-06-25

在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

相关文章

精彩推荐