与状态混合
Mixins with state
我正在研究 "Pickaxe Book" 并且作者给出了以下示例作为在不使用实例变量的情况下提供 module/mixin 状态的技术:
...the module could use a module-level hash, indexed by the current
object ID, to store instance-specific data...
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_id
。 object_id
方法如何能够以这种方式访问 Client
实例?我尝试使用 length
来查看它是否会根据该索引进行索引,但我得到:
NameError: undefined local variable or method `length' for #<Client:0x00000000ecc570>
我想确保我理解这里发生的事情的原则。
如果Client
包括Test
,而c1
是一个Client
,那么object_id
就是c1.object_id
,继承自[=16] =].每个 Ruby 对象都保证是唯一的 object_id
。并非所有对象都保证具有 length
(此外,许多对象将具有非唯一长度,例如 "f"
和 [8]
共享 length
1
) .
How is the object_id method able to access the Client instance in this
manner?
state=()
方法在包含时继承自Test
模块。包含的模块创建一个匿名 class,插入继承链中包含 class 的正上方。
这一行:
c1.state = 'cat'
相当于:
c1.state=('cat')
而当 c1
调用 state=()
时,state=()
方法内部 self
将等于 c1
。在def
中,self
等于调用该方法的对象。
当你调用没有接收者的方法时,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
我正在研究 "Pickaxe Book" 并且作者给出了以下示例作为在不使用实例变量的情况下提供 module/mixin 状态的技术:
...the module could use a module-level hash, indexed by the current object ID, to store instance-specific data...
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_id
。 object_id
方法如何能够以这种方式访问 Client
实例?我尝试使用 length
来查看它是否会根据该索引进行索引,但我得到:
NameError: undefined local variable or method `length' for #<Client:0x00000000ecc570>
我想确保我理解这里发生的事情的原则。
如果Client
包括Test
,而c1
是一个Client
,那么object_id
就是c1.object_id
,继承自[=16] =].每个 Ruby 对象都保证是唯一的 object_id
。并非所有对象都保证具有 length
(此外,许多对象将具有非唯一长度,例如 "f"
和 [8]
共享 length
1
) .
How is the object_id method able to access the Client instance in this manner?
state=()
方法在包含时继承自Test
模块。包含的模块创建一个匿名 class,插入继承链中包含 class 的正上方。这一行:
c1.state = 'cat'
相当于:
c1.state=('cat')
而当
c1
调用state=()
时,state=()
方法内部self
将等于c1
。在def
中,self
等于调用该方法的对象。当你调用没有接收者的方法时,
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