【问题标题】:Mixins with state带状态的混合
【发布时间】:2016-02-09 15:14:09
【问题描述】:

我正在阅读“Pickaxe Book”,作者给出了以下示例,作为在不使用实例变量的情况下提供模块/mixin 状态的技术:

...模块可以使用模块级哈希,由当前索引 对象 ID,用于存储特定于实例的数据...

module Test
  State = {}
  def state=(value)
    State[object_id] = value
  end
  def state
    State[object_id]
  end
end

class Client
  include Test
end

c1 = Client.new
c2 = Client.new
c1.state = 'cat'
c2.state = 'dog'
c1.state # => "cat"
c2.state # => "dog"

我不清楚这到底是如何工作的。特别是object_idobject_id 方法如何能够以这种方式访问​​Client 实例?我尝试使用length 来查看它是否会根据该索引进行索引,但我得到了:

NameError: undefined local variable or method `length' for #<Client:0x00000000ecc570>

我想确保我理解这里发生的事情的原则。

【问题讨论】:

  • 不要在 Stack Overflow 上使用 &lt;pre&gt; 代码,只需缩进 4 个空格。 &lt;pre&gt; 没有进行正确的 HTML 转义,因此看起来像标签的内容(例如 &lt;Client:0x00000000ecc570&gt;)不会显示出来。
  • 哦。哎呀!感谢您的提示。

标签: ruby module state mixins


【解决方案1】:

如果Client 包含Test,并且c1Client,则object_idc1.object_id,继承自Object。每个 Ruby 对象都保证有一个唯一的object_id。并非所有对象都保证具有length(此外,许多对象将具有非唯一长度,例如"f"[8] 共享length1)。

【讨论】:

  • 对不起。我了解object_id 的作用以及继承的工作原理,但我没有理解这里使用object_id 时与使用self.object_id 相同。那是对的吗?我在想object_idState 以某种方式通过[] 调用。哈哈哈我真傻。这就是我尝试length 方法的原因...因为State.methods 显示length 作为一个选项。我知道它不会成为一个好的索引,但我不知道为什么它根本不起作用。现在看来很明显了。
  • 是的,在类中,您可以在没有显式接收者的情况下调用每个方法(事实上,使用私有方法,这是调用它们的唯一方法,除了用send 作弊)。因此,object_idself.object_id 相同;鉴于Test 包含在Client 中,selfc1c2
【解决方案2】:

object_id 方法如何能够访问此中的 Client 实例 方式?

  1. state=() 方法在包含时继承自 Test 模块。被包含的模块创建一个匿名类,该类被插入到继承链中包含类的正上方。

  2. 这一行:

    c1.state = 'cat'
    

    相当于:

    c1.state=('cat')
    

    c1 调用state=() 时,state=() 方法内部的self 将等于c1。在def 中,self 等于调用该方法的对象。

  3. 当您调用没有接收者的方法时,self 是隐式接收者。内state=()

    def state=(value)
      State[object_id] = value
    end
    

    object_id() 方法在没有接收者的情况下被调用,所以self 成为接收者。结果,该行:

    State[object_id] = value
    

    相当于:

    State[self.object_id] = value
    

    相当于:

    State[c1.object_id] = value
    

【讨论】:

  • 谢谢!第 3 点是我一直在逃避的。现在很有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 2011-05-25
相关资源
最近更新 更多