e$B1sF#$G$9!#e(B
1.9 e$B$G$O@55,I=8=$GL>A0$r;H$C$?;2>H$,$G$-$k$N$G!"e(Bsprintf e$B$G$be(B
e$BL>A0$r;H$C$?;2>H$,$G$-$k$HJXMx$8$c$J$$$G$7$g$&$+!#e(B
$ ./ruby -e ‘puts “%d : %f” % { :foo => 1, :bar => 2 }’
1 : 2.000000
$ ./ruby -e ‘printf("%d : %f\n", :foo => 1, :bar => 2)’
1 : 2.000000
e$B$"$^$j%F%9%H$7$F$$$^$;$s$,!"$?$?$-Bf$N<BAu$G$9!#e(B
Index: sprintf.c
— sprintf.c (revision 18638)
+++ sprintf.c (working copy)
@@ -103,18 +103,28 @@
} while (0)
#define GETARG() (nextvalue != Qundef ? nextvalue : \
- posarg < 0 ? \
- posarg == -1 ?
(rb_raise(rb_eArgError, “unnumbered(%d) mixed with numbered”,
nextarg), 0) : \ - posarg == -2 ? \
- (rb_raise(rb_eArgError, “unnumbered(%d) mixed with named”,
nextarg), 0) :
(posarg = nextarg++, GETNTHARG(posarg)))
#define GETPOSARG(n) (posarg > 0 ?
(rb_raise(rb_eArgError, “numbered(%d) after unnumbered(%d)”, n,
posarg), 0) : \
- posarg == -2 ? \
- (rb_raise(rb_eArgError, “numbered(%d) after named”, n), 0) :
((n < 1) ? (rb_raise(rb_eArgError, “invalid index - %d$”, n), 0) :
(posarg = -1, GETNTHARG(n))))
#define GETNTHARG(nth)
((nth >= argc) ? (rb_raise(rb_eArgError, “too few arguments”), 0)
: argv[nth])
+#define GETNAMEARG(id) (posarg > 0 ? \
- (rb_raise(rb_eArgError, “named after unnumbered(%d)”, posarg), 0) :
\ - posarg == -1 ? \
- (rb_raise(rb_eArgError, “named after numbered”), 0) : \
- rb_hash_aref(get_hash(&hash, argc, argv), id))
#define GETNUM(n, val)
for (; p < end && rb_enc_isdigit(*p, enc); p++) {
int next_n = 10 * n + (*p - ‘0’);
@@ -141,7 +151,22 @@
val = NUM2INT(tmp);
} while (0)
+static VALUE
+get_hash(volatile VALUE *hash, int argc, const VALUE *argv)
+{
-
VALUE tmp;
-
if (*hash != Qundef) return *hash;
-
if (argc != 2) {
-
rb_raise(rb_eArgError, “one hash required”);
-
}
-
tmp = rb_check_convert_type(argv[1], T_HASH, “Hash”, “to_hash”);
-
if (NIL_P(tmp)) {
-
rb_raise(rb_eArgError, “one hash required”);
-
}
-
return (*hash = tmp);
+}
/*
- call-seq:
-
format(format_string [, arguments...] ) => string
@@ -412,6 +437,7 @@
VALUE nextvalue;
VALUE tmp;
VALUE str;
- volatile VALUE hash = Qundef;
#define CHECK_FOR_WIDTH(f)
if ((f) & FWIDTH) {
@@ -513,6 +539,22 @@
flags |= FWIDTH;
goto retry;
- case ‘<’:
-
{
- const char *start = p;
- ID id;
- for (; p < end && *p != ‘>’; ) {
-
p += rb_enc_mbclen(p, end, enc);
- }
- if (p >= end) {
-
rb_raise(rb_eArgError, "malformed name - unmatched
parenthesis");
- }
- id = rb_intern3(start + 1, p - start - 1, enc);
- nextvalue = GETNAMEARG(ID2SYM(id));
- p++;
- goto retry;
-
}
- case ‘*’:
CHECK_FOR_WIDTH(flags);
flags |= FWIDTH;