新手问题 关于 Object 和 BasicObject

jojoma · 2016年10月12日 · 最后由 jojoma 回复于 2016年10月12日 · 1847 次阅读

在 RailsCasts 看到个类,分别继承于 Object 和 BasicObject 时,有不同的行为

第一种,继承于 Object

class DynamicDelegator
  def initialize(target)
    @target = target
  end
  def method_missing(*args, &block)
    result = @target.send(*args, &block)
    @target = result if result.kind_of? @target.class
    result
  end
end

# ---------开始测试-----------
> DynamicDelegator.new(Patient.last)
 # => #<DynamicDelegator:0x007fbfec857e98 @target=#<Patient id: 4, first_name: "JO", middle_name: nil, last_name: "JO", birth_date: nil, gender: "Male", status: "Initial", location_id: 1, view_count: 0, is_valid: true, created_at: "2016-09-29 07:36:28", updated_at: "2016-09-29 07:36:28">>
> DynamicDelegator.new(123)
 # => #<DynamicDelegator:0x007fbfeb8c9da0 @target=12>

第二种,继承于 BasicObject

class DynamicDelegator < BasicObject
  def initialize(target)
    @target = target
  end
  def method_missing(*args, &block)
    result = @target.send(*args, &block)
    @target = result if result.kind_of? @target.class
    result
  end
end

# ---------开始测试-----------
> DynamicDelegator.new(Patient.last)
 # => #<Patient id: 4, first_name: "JO", middle_name: nil, last_name: "JO", birth_date: nil, gender: "Male", status: "Initial", location_id: 1, view_count: 0, is_valid: true, created_at: "2016-09-29 07:36:28", updated_at: "2016-09-29 07:36:28">
> DynamicDelegator.new(123)
 # => 123

第一种情况下,返回一个 DynamicDelegator 类实例,参数保存在其实例变量中,是完全可以理解的。 但是,一旦修改继承,返回的是创建时赋的参数。求问这是为啥呢?

可能是 new 的时候,执行了一些不知道的东西,导致这样的结果。可是我记得 new = allocate + initialize,不知道在哪里有了变化?

Ryan 在视频里说,是因为 Object 有较多实例方法,而 BasicObject 没有。所以继承于干净的 BasicObject,能够更好的 delegate。

我看了 Object 和 BasicObject 之间的方法,也没有找到答案...

因为你在打印对象的时候调用了对象的 inspect 方法,但是 inspect 对于 BasicObject 不存在,所以调用了 method_missing,然后 inspect 被 send 回 target,结果存入 result,返回 result

#1 楼 @mizuhashi 原来如此😀 确实,我除去类里面 method_missing 方法之后

2.1.0 :002 > patients = DynamicDelegator.new(1)
(Object doesn't support #inspect)
 =>
jojoma 关闭了讨论。 10月12日 20:42
jojoma 重新开启了讨论。 10月12日 20:43
需要 登录 后方可回复, 如果你还没有账号请 注册新账号