[#80531] Re: [ruby-cvs:65407] normal:r58236 (trunk): thread.c: comments on M:N threading [ci skip] — Eric Wong <normalperson@...>
SASADA Koichi <ko1@ruby-lang.org> wrote:
On 2017/04/02 11:35, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
Eric Wong <normalperson@yhbt.net> wrote:
On 2017/05/08 9:33, Eric Wong wrote:
On 2017/05/08 10:53, SASADA Koichi wrote:
SASADA Koichi <ko1@atdot.net> wrote:
On 2017/05/08 12:01, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
On 2017/05/08 15:36, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
On 2017/05/09 12:38, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
On 2017/05/09 14:12, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
On 2017/05/09 15:23, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
Thank you.
[#80763] [Ruby trunk Feature#13434] better method definition in C API — naruse@...
Issue #13434 has been updated by naruse (Yui NARUSE).
[#80844] [Ruby trunk Bug#13503] Improve performance of some Time & Rational methods — watson1978@...
Issue #13503 has been updated by watson1978 (Shizuo Fujita).
[#80892] [Ruby trunk Misc#13514] [PATCH] thread_pthread.c (native_sleep): preserve old unblock function — ko1@...
Issue #13514 has been updated by ko1 (Koichi Sasada).
ko1@atdot.net wrote:
On 2017/04/27 8:58, Eric Wong wrote:
SASADA Koichi <ko1@atdot.net> wrote:
Eric Wong <normalperson@yhbt.net> wrote:
[ruby-core:80917] [Ruby trunk Bug#13397] #object_id should not be signed
Issue #13397 has been updated by nobu (Nobuyoshi Nakada).
Such feature would be nice, but can't help libraries which support older versions.
```diff
commit 3eb27e2637f506a71d8e86d7318e96a6cbcfff1b
Author: Nobuyoshi Nakada <nobu@ruby-lang.org>
Date: Fri Apr 28 16:35:48 2017
%I for object ID
diff --git a/sprintf.c b/sprintf.c
index f2d51f1c76..758e32fed4 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -25,6 +25,7 @@
static char *fmt_setup(char*,size_t,int,int,int,int);
static char *ruby_ultoa(unsigned long val, char *endp, int base, int octzero);
+static char *ruby_ptoa(VALUE val, char *endp, int base, int octzero);
static char
sign_bits(int base, const char *p)
@@ -781,6 +782,18 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
}
break;
+ case 'I':
+ {
+ VALUE arg = GETARG();
+ prec = (SIZEOF_VOIDP * CHAR_BIT + 3) / 4;
+ CHECK(prec + 2);
+ PUSH_("0x", 2);
+ t = ruby_ptoa(arg, &buf[blen + prec], 16, 0);
+ if (t > &buf[blen]) memset(&buf[blen], '0', t - &buf[blen]);
+ blen += prec;
+ }
+ break;
+
case 'd':
case 'i':
case 'o':
@@ -1255,6 +1268,18 @@ ruby_ultoa(unsigned long val, char *endp, int base, int flags)
return BSD__ultoa(val, endp, base, octzero, xdigs);
}
+static char *
+ruby_ptoa(VALUE val, char *endp, int base, int flags)
+{
+ const char *xdigs = lower_hexdigits;
+ int octzero = flags & FSHARP;
+#ifdef _HAVE_SANE_QUAD_
+ return BSD__uqtoa(val, endp, base, octzero, xdigs);
+#else
+ return BSD__ultoa(val, endp, base, octzero, xdigs);
+#endif
+}
+
int
ruby_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
{
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index 1bf65f1eab..0b7a11a33b 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -513,4 +513,9 @@
assert_equal before + 1, after, 'only new string is the created one'
assert_equal '1970-01-01', val
end
+
+ def test_object_id
+ x = Object.new
+ assert_equal(x.to_s, sprintf("#<%s:%I>", x.class, x))
+ end
end
```
----------------------------------------
Bug #13397: #object_id should not be signed
https://bugs.ruby-lang.org/issues/13397#change-64526
* Author: vo.x (Vit Ondruch)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
* ruby -v: ruby 2.4.0p0 (2016-12-24 revision 57164) [i386-linux]
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
It is surprising that #object_id returns signed value. Let me explain show two examples. Working with 32b Ruby (ruby 2.4.0p0 (2016-12-24 revision 57164) [i386-linux]) to make this issue more apparent.
~~~
$ ruby << \EOR
GC.disable
3_000_000.times { p Object.new.inspect }
EOR
"#<Object:0x57d49a5c>"
"#<Object:0x57d499a8>"
"#<Object:0x57d49930>"
"#<Object:0x57d498b8>"
... snip ...
"#<Object:0x828bf164>"
"#<Object:0x828bf0ec>"
"#<Object:0x828bf074>"
"#<Object:0x828beffc>"
"#<Object:0x828bef84>"
^C-:2:in `p': Interrupt
from -:2:in `block in <main>'
from -:2:in `times'
from -:2:in `<main>'
"#<Object:0x8290b1f4>"
~~~
In this example, the "object_id", which is part of the inspect object is unsigned, since it is printed using C sprintf with %p format. There are other libraries, which tries to mimic the output [ [1] ]. The implementation is approximately following:
~~~
$ ruby << \EOR
GC.disable
class A
DEFAULT_OBJ_ID_STR_WIDTH = 0.size == 4 ? 7 : 14
def inspect
id_str = (object_id << 1).to_s(16).rjust(DEFAULT_OBJ_ID_STR_WIDTH, '0')
"#<#{self.class.name}:0x#{id_str}>"
end
end
3_000_000.times { p A.new.inspect }
EOR
"#<A:0x58585428>"
"#<A:0x585852d4>"
"#<A:0x585851bc>"
"#<A:0x5858507c>"
"#<A:0x58584ec4>"
"#<A:0x58584d5c>"
"#<A:0x58584c1c>"
"#<A:0x58584adc>"
... snip ...
"#<A:0x7fff4888>"
"#<A:0x7fff47c0>"
"#<A:0x7fff46f8>"
"#<A:0x7fff4630>"
"#<A:0x7fff4568>"
"#<A:0x7fff44a0>"
"#<A:0x7fff43d8>"
"#<A:0x7fff4310>"
"#<A:0x7fff4248>"
"#<A:0x7fff4180>"
"#<A:0x7fff40b8>"
"#<A:0x-7fffc034>"
"#<A:0x-7fffc110>"
"#<A:0x-7fffc1ec>"
"#<A:0x-7fffc2c8>"
"#<A:0x-7fffc3a4>"
"#<A:0x-7fffc480>"
"#<A:0x-7fffc55c>"
"#<A:0x-7fffc638>"
^C-:10:in `p': Interrupt
from -:10:in `block in <main>'
from -:10:in `times'
from -:10:in `<main>'
~~~
And the output is quite surprising to me. Why the object_id should be signed value? It doesn't make any sense to me. Is this implementation wrong or is Ruby wrong?
[1]: https://github.com/ruby-concurrency/concurrent-ruby/issues/547
--
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>