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


cremes (Chuck Remes) wrote:
> I have an alternative suggestion. Since @shyouhei says that my original suggestion is too difficult a transition path, here is an alternative.
> ...
> This adds `Thread#local` and `Fiber#local` instance methods. We can then access them very easily:
> 
> ```
> Thread.current.local[:key] = 'thread local value'
> Fiber.current.local[:key] = 'fiber local value'
> ```

This looks good to me.

I think we can make it a bit nicer with:

```
Thread.local[:key] = 'thread local value'
Fiber.local[:key] = 'fiber local value'
```

It's a bit shorter and nicer to read for me.

But also with that API it discourages to get/set the thread/fiber-locals of another thread/fiber,
which is against the purpose of thread/fiber-local variables.
That API does not prevent it though, since one could save the value of `Thread.local` and use it in another thread
(we could enforce it with exceptions or have Thread/Fiber.local return an object always resolving the current Thread).
Sorry for bringing #13245 again but I think it is a very important concern for a new API: communicate the right usage.

One detail, where would we define this Local class?
::Local sounds too risky. Thread::Local or Fiber::Local sounds misleading.
Or maybe Thread.local and Fiber.local should just hold a Hash instance?

----------------------------------------
Feature #13893: Add Fiber#[] and Fiber#[]= and restore Thread#[] and Thread#[]= to their original behavior
https://bugs.ruby-lang.org/issues/13893#change-68093

* Author: cremes (Chuck Remes)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Ruby 3 API cleanup suggestion.

The Thread and Fiber classes have a very odd API for setting/getting thread local and fiber local variables. With Ruby 3 coming soon, this is a perfect opportunity to make this API more coherent and return to the Principal of Least Surprise. The concept of Fibers and Threads should be completely separated and we should no longer assume that a Fiber is attached to any particular Thread.

I suggest this:

```
class Fiber
  # Gets a fiber-local variable.
  def [](index)
    ...
  end

  # Sets a fiber-local variable.
  def []=(index, value)
    ...
  end

  # Returns true if the given +key+ exists as a fiber-local variable.
  def key?(key)
    ...
  end

  # Returns an array of fiber-local variable names as symbols.
  def keys
    ...
  end
end

class Thread
  # Gets a thread-local variable.
  def [](index)
    ...
  end

  # Sets a thread-local variable.
  def []=(index, value)
    ...
  end

  # Returns true if the given +key+ exists as a thread-local variable.
  def key?(key)
    ...
  end

  # Returns an array of thread-local variable names as symbols.
  def keys
    ...
  end
end
```

Also, remove ```Thread#thread_variable?```, `Thread#thread_variable_get`, `Thread#variable_set`, and `Thread#thread_variables` since that behavior is already covered by `Thread#key?`, `Thread#keys`, `Thread#[]`, and `Thread#[]=`. The APIs for both Thread and Fiber are more coherent and less surprising with these changes.



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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>