[前][次][番号順一覧][スレッド一覧]

ruby-changes:45610

From: nobu <ko1@a...>
Date: Wed, 22 Feb 2017 16:16:19 +0900 (JST)
Subject: [ruby-changes:45610] nobu:r57683 (trunk): Thread#fetch

nobu	2017-02-22 16:16:13 +0900 (Wed, 22 Feb 2017)

  New Revision: 57683

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57683

  Log:
    Thread#fetch
    
    * thread.c (rb_thread_fetch): add new method Thread#fetch.
      [Feature #13009]

  Modified files:
    trunk/NEWS
    trunk/test/ruby/test_thread.rb
    trunk/thread.c
Index: thread.c
===================================================================
--- thread.c	(revision 57682)
+++ thread.c	(revision 57683)
@@ -3091,6 +3091,39 @@ rb_thread_aref(VALUE thread, VALUE key) https://github.com/ruby/ruby/blob/trunk/thread.c#L3091
 }
 
 static VALUE
+rb_thread_fetch(int argc, VALUE *argv, VALUE self)
+{
+    VALUE key, val;
+    ID id;
+    rb_thread_t *th;
+    int block_given;
+
+    rb_check_arity(argc, 1, 2);
+    key = argv[0];
+
+    block_given = rb_block_given_p();
+    if (block_given && argc == 2) {
+	rb_warn("block supersedes default value argument");
+    }
+
+    id = rb_check_id(&key);
+    GetThreadPtr(self, th);
+
+    if (id == recursive_key) {
+	return th->local_storage_recursive_hash;
+    }
+    if (id && th->local_storage && st_lookup(th->local_storage, id, &val)) {
+	return val;
+    }
+    if (block_given)
+	return rb_yield(key);
+    else if (argc == 1)
+	rb_raise(rb_eKeyError, "key not found: %"PRIsVALUE, key);
+    else
+	return argv[1];
+}
+
+static VALUE
 threadptr_local_aset(rb_thread_t *th, ID id, VALUE val)
 {
     if (id == recursive_key) {
@@ -4796,6 +4829,7 @@ Init_Thread(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L4829
     rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0);
     rb_define_method(rb_cThread, "[]", rb_thread_aref, 1);
     rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2);
+    rb_define_method(rb_cThread, "fetch", rb_thread_fetch, -1);
     rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1);
     rb_define_method(rb_cThread, "keys", rb_thread_keys, 0);
     rb_define_method(rb_cThread, "priority", rb_thread_priority, 0);
Index: NEWS
===================================================================
--- NEWS	(revision 57682)
+++ NEWS	(revision 57683)
@@ -24,6 +24,10 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L24
   * Update Onigmo 6.1.1.
     * Support absent operator https://github.com/k-takata/Onigmo/issues/82
 
+* Thread
+
+  * Thread#fetch  [Feature #13009]
+
 === Stdlib updates (outstanding ones only)
 
 === Compatibility issues (excluding feature bug fixes)
Index: test/ruby/test_thread.rb
===================================================================
--- test/ruby/test_thread.rb	(revision 57682)
+++ test/ruby/test_thread.rb	(revision 57683)
@@ -482,6 +482,36 @@ class TestThread < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L482
     t.kill if t
   end
 
+  def test_thread_local_fetch
+    t = Thread.new { sleep }
+
+    assert_equal(false, t.key?(:foo))
+
+    t["foo"] = "foo"
+    t["bar"] = "bar"
+    t["baz"] = "baz"
+
+    x = nil
+    assert_equal("foo", t.fetch(:foo, 0))
+    assert_equal("foo", t.fetch(:foo) {x = true})
+    assert_nil(x)
+    assert_equal("foo", t.fetch("foo", 0))
+    assert_equal("foo", t.fetch("foo") {x = true})
+    assert_nil(x)
+
+    x = nil
+    assert_equal(0, t.fetch(:qux, 0))
+    assert_equal(1, t.fetch(:qux) {x = 1})
+    assert_equal(1, x)
+    assert_equal(2, t.fetch("qux", 2))
+    assert_equal(3, t.fetch("qux") {x = 3})
+    assert_equal(3, x)
+
+    assert_raise(KeyError) {t.fetch(:qux)}
+  ensure
+    t.kill if t
+  end
+
   def test_thread_local_security
     assert_raise(RuntimeError) do
       Thread.new do

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]