Issue #7097 has been updated by Eregon (Benoit Daloze).


tenderlovemaking (Aaron Patterson) wrote:
> I spoke with ko1-san and Usa-san last night, and we thought that thread_variable_(get|set) would be good (similar to instance_variable_(get|set)).  I've attached an updated patch to make that change.  The documentation includes examples of how the thread local storage and fiber local storage are different.
> 
> I added two more methods:
> 
>   * Thread#thread_variables # => returns a list of the defined variable keys
>   * Thread#thread_variable? # => returns true if a key is set, otherwise false
> 
> Thread#local_variable_(get|set) methods respect the same security and frozen behavior as Thread#[] and Thread#[]=.

Sounds great, but I feel the "thread_" prefix is redundant given it is called on a Thread object.
I'm thinking to two alternatives:

* Remove the "thread_" prefix (as usually the thread instance is Thread.current which is very explicit, or the variable name should be clear enough).

    Thread.current.variable_get(:var)
    thread.variable_get(:var)
    worker.variable_get(:var)
    # versus
    Thread.current.thread_variable_get(:var)
    thread.thread_variable_get(:var)
    worker.thread_variable_get(:var)

Also, I think get/set do not feel very ruby-like, so ...

* Use a API resembling fiber locals:

Thread#locals # => returns an object responding to #[] and #[]= (and maybe #variables and #include?)

    Thread.current.locals[:var] = some_value
    Thread.current.locals[:var]

I guess exposing the whole Hash is exposing internal structures and so is unreasonable. But doing so would be intuitive and avoid having 4 new methods for 4 well-known ([],[]=,keys,include?).
----------------------------------------
Bug #7097: Thread locals don't work inside Enumerator
https://bugs.ruby-lang.org/issues/7097#change-31612

Author: tenderlovemaking (Aaron Patterson)
Status: Assigned
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: 
Target version: 
ruby -v: ruby 2.0.0dev (2012-09-25 trunk 37032) [x86_64-darwin12.2.0]


I set a thread local outside an Enumerator.  The Enumerator runs inside the same thread where I set the local.  I would expect the thread local to be available since I am in the same thread, but it is not.

Here is a test that shows the problem:

require 'minitest/autorun'

class ThreadLocalBreaks < MiniTest::Unit::TestCase
  def test_thread_local_in_enumerator
    Thread.current[:foo] = "bar"

    thread, value = Enumerator.new { |y|
      y << [Thread.current, Thread.current[:foo]]
    }.next

    assert_equal Thread.current, thread       # passes
    assert_equal Thread.current[:foo], value  # fails
  end
end



-- 
http://bugs.ruby-lang.org/