Ruby 示例中的 DCI 中的 Thread.current 是啥?
Posted
技术标签:
【中文标题】Ruby 示例中的 DCI 中的 Thread.current 是啥?【英文标题】:What is Thread.current for in the DCI in Ruby example?Ruby 示例中的 DCI 中的 Thread.current 是什么? 【发布时间】:2015-11-27 14:28:26 【问题描述】:这段代码中的Thread.current
是什么意思?我正在查看this 在 Rails 应用程序中使用 DCI 的示例。在 lib/context.rb 中,有这样的:
module Context
include ContextAccessor
def context=(ctx)
Thread.current[:context] = ctx
end
def in_context
old_context = self.context
self.context = self
res = yield
self.context = old_context
res
end
end
在应用程序/上下文中的各种上下文中使用,例如:
def bid
in_context do
validator.validate
biddable.create_bid
end
#...
end
在in_context
块中运行代码并在当前线程上设置键值对有什么好处?
【问题讨论】:
它基本上是一个全局变量。只有线程安全。 【参考方案1】:通常,在块内部,您无法访问调用者的上下文(除了闭包变量。)
▶ class A
▷ attr_accessor :a
▷ def test
▷ yield if block_given?
▷ end
▷ end
#⇒ :test
▶ inst = A.new
#⇒ #<A:0x00000006f41e28>
▶ inst.a = 'Test'
#⇒ "Test"
▶ inst.test do
▷ puts self
▷ # here you do not have an access to inst at all
▷ # this would raise an exception: puts self.a
▷ end
#⇒ main
但是根据上下文,您仍然可以从块内部访问inst
:
▶ in_context do
▷ puts self.context.a
▷ end
#⇒ 'Test'
因此,可以引入proc
(考虑A
和B
都包含Context
):
▶ pr = ->() puts self.context
▶ A.new.in_context &pr
#⇒ #<A:0x00000006f41e28>
▶ B.new.in_context &pr
#⇒ #<B:0x00000006f41eff>
现在外部proc
pr
几乎可以完全访问其调用者。
【讨论】:
【参考方案2】:Thread.current
需要支持多线程应用程序,其中每个线程都有自己的上下文。
还包括ContextAccessor
module,其中包含上下文。将它们放在一起只会给出更清晰的画面:
# context.rb
def context=(ctx)
Thread.current[:context] = ctx
end
# context_accessor.rb
def context
Thread.current[:context]
end
in_context
方法旨在安全地更改其块内的上下文。无论更改是什么,当块结束执行时,旧的上下文都会恢复。
【讨论】:
以上是关于Ruby 示例中的 DCI 中的 Thread.current 是啥?的主要内容,如果未能解决你的问题,请参考以下文章
ruby 描述Ruby中的DCI(数据,上下文,交互)架构。