什么是线程?在Ruby中的DCI示例中



代码中的Thread.current是什么?我正在查看在Rails应用程序中使用DCI的示例。在lib/上下文。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

在app/contexts的不同上下文中使用,例如:

def bid
  in_context do
    validator.validate
    biddable.create_bid
  end
  #...
end

in_context块中运行代码并在当前线程上设置键值对有什么好处?

一般来说,在块中你不能访问调用者的上下文(除了闭包变量)

▶ 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(考虑AB都包含Context):
▶ pr = ->() { puts self.context }
▶ A.new.in_context &pr
#⇒ #<A:0x00000006f41e28>
▶ B.new.in_context &pr
#⇒ #<B:0x00000006f41eff>

现在外部proc pr 几乎完全访问它的调用者

Thread.current需要支持多线程应用程序,其中每个线程都有自己的上下文。

还包括ContextAccessor模块,其中一个获得上下文。把它们放在一起就能给出更清晰的画面:

# context.rb
def context=(ctx)
  Thread.current[:context] = ctx
end
# context_accessor.rb
def context
  Thread.current[:context]
end

in_context方法被设计为安全地更改其块内的上下文。无论更改是什么,当块结束执行时,旧上下文将恢复。

相关内容

  • 没有找到相关文章

最新更新