From: "Eregon (Benoit Daloze)" Date: 2012-10-27T05:09:36+09:00 Subject: [ruby-core:48330] [ruby-trunk - Bug #7097] Thread locals don't work inside Enumerator Issue #7097 has been updated by Eregon (Benoit Daloze). Aaron wrote: > On Fri, Oct 26, 2012 at 11:38:19PM +0900, Eregon (Benoit Daloze) wrote: > > * Remove the "thread_" prefix (as usually the thread instance is Thread.current which is very explicit, or the variable name should be clear enough). > > If it becomes cumbersome, we can add aliases later. get/set aren't very > ruby-like, but we have other examples (instance_variable_(get|set)). Yeah, I think these examples are not particularly the best, but I see no other good name (well, #[] and #[]= but they are already taken). I'd rather remove the 'thread_' prefix from now, but it makes sense to follow instance_variable_{get,set}. > I'd rather not expose another object. We can't just expose the hash > object because it would have inconsistent behavior with fiber locals: > > irb(main):001:0> t = Thread.new { }.join > => # > irb(main):002:0> t[:foo] = "bar" > => "bar" > irb(main):003:0> t["foo"] > => "bar" > irb(main):004:0> > > Also, we'd have to figure out what calling `freeze` on that hash means. > Because of these things, we would have to expose a new object that isn't > a Hash. Exposing a new object means propagating things like > Thread#freeze down to the new object. I understand your concern, indeed it's giving too much freedom to the user (and too less to implementers). > If we implement these 4 new method in my patch, our API footprint is > only increased by 4 new methods (vs 5 methods + a new object type). If > we find later on that exposing an object is a good thing, we can easily > implement these 4 methods in terms of the new object and deprecate the > 4 methods. Going in the other direction, deprecating an object, is not > so easy. > > I don't particularly care what the method names are (since we can just > alias them later), but I'm firmly against exposing a new object. I see, this was a bold suggestion (which I made because I would greatly prefer that API), but it has too much drawbacks and complexity. Thank you for answering it in details. ---------------------------------------- Bug #7097: Thread locals don't work inside Enumerator https://bugs.ruby-lang.org/issues/7097#change-31635 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/