From: "Florian Groß" Date: 2004-12-27T13:02:41+09:00 Subject: Allowing custom number literal suffixes? --------------050401010903050703090907 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Moin! On the ruby-muse mailing list which is a place for discussion of new ideas for Ruby there recently was a sub-thread concerning the introduction of user-defined number literal suffixes. These suffixes are already used in other languages and look like 1.5f or 0.6r. I think having these would be nice for user-defined numeric Classes like Rational (currently these overload 1/2 under mathn and other operations which can be a problem) and imaginary numbers (via the Complex class). I think being able to write 0.5r instead of the much longer Rational.reduce(1, 2), 2i instead of Complex.new(2, 1) or 5.1b instead of BigDecimal.new("5.1") would be a nice thing that would not have many downsides. Peter Vanbroekhoven was able to come up with a fairly simple and efficient patch which I have reattached to this mail. With it applied you can write 1.5x and it will call number_literal_x("1.5") and return the result. However I might be overlooking issues that are associated with this enhancement and I know that having useless features leads to language bloat. So what do the community and matz think about this? Would this be useful to you? Thank you all in advance for feedback. Regards, Florian Gross --------------050401010903050703090907 Content-Type: text/plain; name="number-literal-patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="number-literal-patch.txt" --- eval.c 13 Oct 2004 19:45:26 -0000 1.1.1.1 +++ eval.c 26 Dec 2004 23:38:50 -0000 1.1.1.1.22.2 @@ -7527,6 +7527,13 @@ ruby_safe_level = safe; } +static VALUE +rb_number_literal_f(obj, s) + VALUE obj, s; +{ + return rb_float_new(rb_str_to_dbl(s, Qfalse)); +} + void Init_eval() { @@ -7623,6 +7630,8 @@ rb_global_variable(&trace_func); rb_define_virtual_variable("$SAFE", safe_getter, safe_setter); + + rb_define_method(rb_mKernel, "number_literal_f", rb_number_literal_f, 1); } /* --- parse.y 13 Oct 2004 19:46:40 -0000 1.1.1.1 +++ parse.y 26 Dec 2004 23:38:51 -0000 1.1.1.1.22.3 @@ -244,7 +244,7 @@ k__FILE__ %token tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR -%token tINTEGER tFLOAT tSTRING_CONTENT +%token tINTEGER tFLOAT tSTRING_CONTENT tNUMBER_LITERAL %token tNTH_REF tBACK_REF %token tREGEXP_END @@ -2131,6 +2131,7 @@ ; numeric : tINTEGER + | tNUMBER_LITERAL | tFLOAT | tUMINUS_NUM tINTEGER %prec tLOWEST { @@ -3923,6 +3924,19 @@ decode_num: pushback(c); + if (nondigit && ISALPHA(nondigit)) { + c = nondigit; + } + if (ISALPHA(c)) { + char name[17] = "number_literal_*"; + name[15] = c; + NODE *str; + tokfix(); + str = NEW_LIST(NEW_STR(rb_str_new(tok(), toklen()))); + nextc(); + yylval.node = NEW_FCALL(rb_intern(name), str); + return tNUMBER_LITERAL; + } tokfix(); if (nondigit) { char tmp[30]; --- ext/bigdecimal/bigdecimal.c 13 Oct 2004 19:48:30 -0000 1.1.1.1 +++ ext/bigdecimal/bigdecimal.c 26 Dec 2004 01:19:20 -0000 1.1.1.1.22.1 @@ -1217,6 +1217,19 @@ } static VALUE +rb_number_literal_b(obj, s) + VALUE obj, s; +{ + ENTER(5); + Real *pv; + + SafeStringValue(s); + GUARD_OBJ(pv, VpCreateRbObject(0, RSTRING(s)->ptr)); + + return ToValue(pv); +} + +static VALUE BigDecimal_limit(int argc, VALUE *argv, VALUE self) { VALUE nFig; @@ -1346,6 +1359,8 @@ rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0); rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); + + rb_define_method(rb_mKernel, "number_literal_b", rb_number_literal_b, 1); } /* --------------050401010903050703090907--