From: Warren Brown Date: 2003-05-02T10:18:36+09:00 Subject: [PATCH] ljust, rjust, and center with pad string (was ljust, rjust...) This is a multi-part message in MIME format. ------=_NextPart_000_000A_01C3101E.C1E68840 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit > How about allowing `ljust' and `rjust' take an > additional parameter (which defaults to the string > " ") which specifies what it justifies with? > > 15.to_s.rjust(5) # --> " 15" > 15.to_s.rjust(5,'0') # --> "00015" > 15.to_s.rjust(5,'blue') # --> "blu15" > > What do you think? I agree wholeheartedly. The problem is made even worse by the fact that '%05s' does *not* pad with leading zeros. I have had to get around this shortfall by doing things like: foo.to_s.rjust(10).sub(/^ {,10}/,'0') Not only is this not very readable, but it is also fairly inefficient. I also find the lack of a padding string parameter very surprising since every other language I have run across that implements padding functions allows (or even requires) you to specify the padding string. If you don't believe me, do a Google search on "lpad function" and just *try* to find one that doesn't :o) All in all, this would seem to be a real benefit to the language, is easy to implement, and should not break any existing code. To expedite things, I have attached a patch that unifies the three functions (ljust, rjust, and center) and adds this functionality. The patch can be applied to last night's snapshot. I have performed a moderate amount of testing on this patch and it seems OK. One quirk: a zero-length second parameter like "'x'.ljust(10,nil)" or "'x'.ljust(10,'')" behaves like "'x'.ljust(10)". A generalized "justify" function similar to the one implemented in this patch might be a nice addition to the language too. - Warren Brown ------=_NextPart_000_000A_01C3101E.C1E68840 Content-Type: application/octet-stream; name="string.c.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="string.c.diff" --- string.c.orig Sun Apr 27 09:13:25 2003=0A= +++ string.c Thu May 1 19:38:06 2003=0A= @@ -3120,70 +3120,100 @@=0A= }=0A= }=0A= =0A= +static VALUE=0A= +rb_str_justify(argc, argv, str, jflag)=0A= + int argc;=0A= + VALUE *argv;=0A= + VALUE str;=0A= + char jflag;=0A= +{=0A= + VALUE w;=0A= + long width, flen =3D 0;=0A= + VALUE res;=0A= + char *p, *pend, *f =3D " ";=0A= + long n;=0A= + VALUE pad;=0A= +=0A= + if (rb_scan_args(argc, argv, "11", &w, &pad) =3D=3D 2) {=0A= + if (!NIL_P(pad)) {=0A= + StringValue(pad);=0A= + if (RSTRING(pad)->len > 0) {=0A= + f =3D RSTRING(pad)->ptr;=0A= + flen =3D RSTRING(pad)->len;=0A= + }=0A= + }=0A= + }=0A= + width =3D NUM2LONG(w);=0A= + if (width < 0 || RSTRING(str)->len >=3D width) return = rb_str_dup(str);=0A= + res =3D rb_str_new5(str, 0, width);=0A= + p =3D RSTRING(res)->ptr;=0A= + if (jflag !=3D 'l') {=0A= + n =3D width - RSTRING(str)->len;=0A= + pend =3D p + ((jflag =3D=3D 'r') ? n : n/2);=0A= + if (flen <=3D 1) {=0A= + while (p < pend) {=0A= + *p++ =3D *f;=0A= + }=0A= + }=0A= + else {=0A= + char *q =3D f;=0A= + while (p + flen <=3D pend) {=0A= + memcpy(p,f,flen);=0A= + p +=3D flen;=0A= + }=0A= + while (p < pend) {=0A= + *p++ =3D *q++;=0A= + }=0A= + }=0A= + }=0A= + memcpy(p, RSTRING(str)->ptr, RSTRING(str)->len);=0A= + if (jflag !=3D 'r') {=0A= + p +=3D RSTRING(str)->len; pend =3D RSTRING(res)->ptr + width;=0A= + if (flen <=3D 1) {=0A= + while (p < pend) {=0A= + *p++ =3D *f;=0A= + }=0A= + }=0A= + else {=0A= + while (p + flen <=3D pend) {=0A= + memcpy(p,f,flen);=0A= + p +=3D flen;=0A= + }=0A= + while (p < pend) {=0A= + *p++ =3D *f++;=0A= + }=0A= + }=0A= + }=0A= + OBJ_INFECT(res, str);=0A= + if (flen > 0) OBJ_INFECT(res, pad);=0A= + return res;=0A= +}=0A= +=0A= static VALUE=0A= -rb_str_ljust(str, w)=0A= +rb_str_ljust(argc, argv, str)=0A= + int argc;=0A= + VALUE *argv;=0A= VALUE str;=0A= - VALUE w;=0A= {=0A= - long width =3D NUM2LONG(w);=0A= - VALUE res;=0A= - char *p, *pend;=0A= -=0A= - if (width < 0 || RSTRING(str)->len >=3D width) return = rb_str_dup(str);=0A= - res =3D rb_str_new5(str, 0, width);=0A= - memcpy(RSTRING(res)->ptr, RSTRING(str)->ptr, RSTRING(str)->len);=0A= - p =3D RSTRING(res)->ptr + RSTRING(str)->len; pend =3D = RSTRING(res)->ptr + width;=0A= - while (p < pend) {=0A= - *p++ =3D ' ';=0A= - }=0A= - OBJ_INFECT(res, str);=0A= - return res;=0A= + return rb_str_justify(argc, argv, str, 'l');=0A= }=0A= =0A= static VALUE=0A= -rb_str_rjust(str, w)=0A= +rb_str_rjust(argc, argv, str)=0A= + int argc;=0A= + VALUE *argv;=0A= VALUE str;=0A= - VALUE w;=0A= {=0A= - long width =3D NUM2LONG(w);=0A= - VALUE res;=0A= - char *p, *pend;=0A= -=0A= - if (width < 0 || RSTRING(str)->len >=3D width) return = rb_str_dup(str);=0A= - res =3D rb_str_new5(str, 0, width);=0A= - p =3D RSTRING(res)->ptr; pend =3D p + width - RSTRING(str)->len;=0A= - while (p < pend) {=0A= - *p++ =3D ' ';=0A= - }=0A= - memcpy(pend, RSTRING(str)->ptr, RSTRING(str)->len);=0A= - OBJ_INFECT(res, str);=0A= - return res;=0A= + return rb_str_justify(argc, argv, str, 'r');=0A= }=0A= =0A= static VALUE=0A= -rb_str_center(str, w)=0A= +rb_str_center(argc, argv, str)=0A= + int argc;=0A= + VALUE *argv;=0A= VALUE str;=0A= - VALUE w;=0A= {=0A= - long width =3D NUM2LONG(w);=0A= - VALUE res;=0A= - char *p, *pend;=0A= - long n;=0A= -=0A= - if (width < 0 || RSTRING(str)->len >=3D width) return = rb_str_dup(str);=0A= - res =3D rb_str_new5(str, 0, width);=0A= - n =3D (width - RSTRING(str)->len)/2;=0A= - p =3D RSTRING(res)->ptr; pend =3D p + n;=0A= - while (p < pend) {=0A= - *p++ =3D ' ';=0A= - }=0A= - memcpy(pend, RSTRING(str)->ptr, RSTRING(str)->len);=0A= - p =3D pend + RSTRING(str)->len; pend =3D RSTRING(res)->ptr + width;=0A= - while (p < pend) {=0A= - *p++ =3D ' ';=0A= - }=0A= - OBJ_INFECT(res, str);=0A= - return res;=0A= + return rb_str_justify(argc, argv, str, 'c');=0A= }=0A= =0A= void=0A= @@ -3265,9 +3295,9 @@=0A= =0A= rb_define_method(rb_cString, "scan", rb_str_scan, 1);=0A= =0A= - rb_define_method(rb_cString, "ljust", rb_str_ljust, 1);=0A= - rb_define_method(rb_cString, "rjust", rb_str_rjust, 1);=0A= - rb_define_method(rb_cString, "center", rb_str_center, 1);=0A= + rb_define_method(rb_cString, "ljust", rb_str_ljust, -1);=0A= + rb_define_method(rb_cString, "rjust", rb_str_rjust, -1);=0A= + rb_define_method(rb_cString, "center", rb_str_center, -1);=0A= =0A= rb_define_method(rb_cString, "sub", rb_str_sub, -1);=0A= rb_define_method(rb_cString, "gsub", rb_str_gsub, -1);=0A= ------=_NextPart_000_000A_01C3101E.C1E68840--