[#36672] [Bug #616] instance_eval and Module#to_s — Shyouhei Urabe <redmine@...>

Bug #616: instance_eval and Module#to_s

12 messages 2008/10/06

[#36750] [Bug #650] Marshal.load raises RegexpError — Shyouhei Urabe <redmine@...>

Bug #650: Marshal.load raises RegexpError

30 messages 2008/10/15
[#36769] Re: [Bug #650] Marshal.load raises RegexpError — Yukihiro Matsumoto <matz@...> 2008/10/17

まつもと ゆきひろです

[#36771] Re: [Bug #650] Marshal.load raises RegexpError — Urabe Shyouhei <shyouhei@...> 2008/10/17

卜部です。

[#36772] Re: [Bug #650] Marshal.load raises RegexpError — Yukihiro Matsumoto <matz@...> 2008/10/17

まつもと ゆきひろです

[#36773] Re: [Bug #650] Marshal.load raises RegexpError — Urabe Shyouhei <shyouhei@...> 2008/10/17

卜部です。

[#36784] Re: [Bug #650] Marshal.load raises RegexpError — Yukihiro Matsumoto <matz@...> 2008/10/18

まつもと ゆきひろです

[#36785] Re: [Bug #650] Marshal.load raises RegexpError — Urabe Shyouhei <shyouhei@...> 2008/10/18

卜部です。

[#36793] Re: [Bug #650] Marshal.load raises RegexpError — Yukihiro Matsumoto <matz@...> 2008/10/19

まつもと ゆきひろです

[#36794] Re: [Bug #650] Marshal.load raises RegexpError — Urabe Shyouhei <shyouhei@...> 2008/10/19

Yukihiro Matsumoto さんは書きました:

[#36823] Re: [Bug #650] Marshal.load raises RegexpError — Yukihiro Matsumoto <matz@...> 2008/10/21

まつもと ゆきひろです

[#36830] Re: [Bug #650] Marshal.load raises RegexpError — Urabe Shyouhei <shyouhei@...> 2008/10/21

もとの正規表現にバグがあるのは認めますが、それに巻き込まれてでかいPStore

[#36833] Re: [Bug #650] Marshal.load raises RegexpError — Yukihiro Matsumoto <matz@...> 2008/10/21

まつもと ゆきひろです

[#36764] Re: [ruby-cvs:27036] Ruby:r19818 (trunk): * transcode.c (str_transcode0): String#encode without argument now — Martin Duerst <duerst@...>

まつもとさん、こんばんは。

11 messages 2008/10/17
[#36767] Re: [ruby-cvs:27036] Ruby:r19818 (trunk): * transcode.c (str_transcode0): String#encode without argument now — Yukihiro Matsumoto <matz@...> 2008/10/17

まつもと ゆきひろです

[#36799] Re: [ruby-cvs:27036] Ruby:r19818 (trunk): * transcode.c (str_transcode0): String#encode without argument now — Martin Duerst <duerst@...> 2008/10/20

まつもとさん、こんにちは。

[#36774] ConverterNotFoundError while making Ruby in Windows(trunk) — Masaki Suketa <masaki.suketa@...>

助田です。

13 messages 2008/10/17
[#36797] Re: ConverterNotFoundError while making Ruby in Windows(trunk) — "U.Nakamura" <usa@...> 2008/10/20

こんにちは、なかむら(う)です。

[#36800] Re: ConverterNotFoundError while making Ruby in Windows(trunk) — "U.Nakamura" <usa@...> 2008/10/20

こんにちは、なかむら(う)です。

[#36789] [Bug #660] 数字を3桁ずつコンマで区切るsprintf書式指定 — "rubikitch ." <redmine@...>

Bug #660: 数字を3桁ずつコンマで区切るsprintf書式指定

13 messages 2008/10/19

[#37007] [Bug:1.9] 1+1+1+...+1 dumps core — "Yusuke ENDOH" <mame@...>

遠藤です。

13 messages 2008/10/31

[ruby-dev:36851] Re: [Bug #660] 数字を3桁ずつコンマで区切るsprintf書式指定

From: "Yusuke ENDOH" <mame@...>
Date: 2008-10-21 14:53:15 UTC
List: ruby-dev #36851
遠藤です。

2008/10/21 15:09 Yukihiro Matsumoto <matz@ruby-lang.org>:
> まつもと ゆきひろです
>
> In message "Re: [ruby-dev:36816] Re: [Bug #660]         数字を3桁ずつコンマで区切るsprintf書式指定"
>    on Tue, 21 Oct 2008 09:14:12 +0900, Fujioka <fuj@rabbix.jp> writes:
>
> |> また、printfの実装では他の部分ではかたくなにlocale使用を拒否
> |> しているのに、ここだけlocaleに従うというのも変な話です。
> |>
> |rubikitchさんも
> |
> |最初の段階では「%,d」や「%_d」で自分で決めるのがいいですね。
> |「localeに決めさせる」という要望が出るかどうかも定かではないので。
> |
> |と発言しているので、ロケールの話は置いといて、
> |3桁の区切りの話だけでいいのではないかと思います。
>
> それならそれで、
>
>  * 「,」や「_」は他の言語でformatを拡張するために使われてい
>    たりしないのか
>
>  * 3桁区切りだけでよいのか、あるいは桁数を指定できるように
>    するのか
>
> など、いろいろ考えるべきことはあると思います。まあ、すぐには
> 入れられないでしょうから、ゆっくり議論すればいいことですが。


たたき台として、

$ ./ruby -e 'p "%_d" % 1000000'
"1_000_000"

となるようにパッチを書いてみました。が、

$ ./ruby -e 'p "%3_ 12d" % 1000000'
"     1_000_000"
$ ./ruby -e 'p "%3_012d" % 1000000'
"000_001_000_000"

で結果の幅が変わるのがそこはかとなく気持ち悪いですね。
prec の幅指定を優先するとすると、

$ ./ruby -e 'p "%3_012d" % 1000000'
"_001_000_000"

になりそうですが、これも気持ち悪いです。


Index: sprintf.c
===================================================================
--- sprintf.c	(revision 19874)
+++ sprintf.c	(working copy)
@@ -437,6 +437,8 @@
     VALUE nextvalue;
     VALUE tmp;
     VALUE str;
+    int delimit_length;
+    char delimiter;
     volatile VALUE hash = Qundef;

 #define CHECK_FOR_WIDTH(f)				 \
@@ -483,6 +485,8 @@

 	width = prec = -1;
 	nextvalue = Qundef;
+	delimit_length = 0;
+	delimiter = '\0';
       retry:
 	switch (*p) {
 	  default:
@@ -522,6 +526,15 @@
 	    p++;
 	    goto retry;

+	  case ',': case '_':
+	    if (delimit_length != 0) {
+		rb_raise(rb_eArgError, "delimiter given twice - %c", *p);
+	    }
+	    delimit_length = 3;
+	    delimiter = *p;
+	    p++;
+	    goto retry;
+
 	  case '1': case '2': case '3': case '4':
 	  case '5': case '6': case '7': case '8': case '9':
 	    n = 0;
@@ -534,6 +547,15 @@
 		p++;
 		goto retry;
 	    }
+	    if (*p == ',' || *p == '_') {
+		if (delimit_length != 0) {
+		    rb_raise(rb_eArgError, "delimiter given twice - %d%c", n, *p);
+		}
+		delimit_length = n;
+		delimiter = *p;
+		p++;
+		goto retry;
+	    }
 	    CHECK_FOR_WIDTH(flags);
 	    width = n;
 	    flags |= FWIDTH;
@@ -705,7 +727,7 @@
 		char fbuf[32], nbuf[64], *s;
 		const char *prefix = 0;
 		int sign = 0, dots = 0;
-		char sc = 0;
+		char sc = 0, c = 0;
 		long v = 0;
 		int base, bignum = 0;
 		int len, pos;
@@ -925,26 +947,40 @@
 		    int plen = strlen(prefix);
 		    PUSH(prefix, plen);
 		}
-		CHECK(prec - len);
 		if (dots) PUSH("..", 2);
 		if (!bignum && v < 0) {
-		    char c = sign_bits(base, p);
-		    while (len < prec--) {
-			buf[blen++] = c;
-		    }
+		    c = sign_bits(base, p);
 		}
 		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
-		    char c;
-
 		    if (!sign && bignum && !RBIGNUM_SIGN(val))
 			c = sign_bits(base, p);
 		    else
 			c = '0';
-		    while (len < prec--) {
-			buf[blen++] = c;
+		}
+		if (delimit_length == 0) {
+		    if (c != 0) FILL(c, prec - len);
+		    PUSH(s, len);
+		}
+		else {
+		    int i;
+		    if (c != 0) {
+			i = (prec - 1) % delimit_length + 1;
+			while (prec - len >= i) {
+			    FILL(c, i);
+			    PUSH(&delimiter, 1);
+			    prec -= i;
+			    i = delimit_length;
+			}
+			if (prec - len > 0) FILL(c, prec - len);
 		    }
+		    i = (len - 1) % delimit_length + 1;
+		    PUSH(s, i);
+		    for (len -= i; len > 0; len -= delimit_length) {
+			PUSH(&delimiter, 1);
+			PUSH(&s[i], delimit_length);
+			i += delimit_length;
+		    }
 		}
-		PUSH(s, len);
 		CHECK(width);
 		while (width-- > 0) {
 		    buf[blen++] = ' ';

-- 
Yusuke ENDOH <mame@tsg.ne.jp>

In This Thread