From: Nobuyoshi Nakada Date: 2009-06-07T02:28:36+09:00 Subject: Re: Iconv and incompatible encodings Hi, At Sun, 7 Jun 2009 00:24:55 +0900, Adam Strzelecki wrote in [ruby-talk:338586]: > Thanks, your solution is really more Ruby-way. I just wonder why > "setlocale" isn't a part of Ruby standard library. Since Ruby maps/wraps > most of the standard (POSIX) functions (especially those available on > Windows too), this one should be also taken into consideration. It affects library functions, such as printf(), and can cause problems. > > First of all, option after // is GNU iconv local extension. > Sure I know that, but it doesn't mean it is EVIL, is it? Still it is > very useful for creating permalinks and removing accented characters > simply, w/o using any third party libraries and so, but unusable until > we call POSIX setlocale, which isn't present in Ruby API. You can't rely on it if you want write portable script. > > Second, extconf.rb must check for the necessary header, and > > whether each categories are defined. > > Still it should be present on every system (AFAIK it is), since quoting > man: "The setlocale() function conforms to ISO/IEC 9899:1999 (``ISO > C99'').". Is there anyone who checks whether exists? Not all systems conform to C99, and not all categories are available on all systems. For instance, mingw and perhaps mswin don't have LC_MESSAGES. > > And it feels too redundant. I guess Locale.ctype = '' would be easy. > > Sure yours is better. Mine didn't consider fact that some of constants > may have different values on different systems. Of course, otherwise why they need the macros? > If it is was to be included into standard library I'd leave > Locale::setlocale method as well, as you may combine types there and > also check returned value, where nil means failed association and String > on successful one, where documentation doesn't explicitly say that > returned string is exactly the one that was passed. So with simple > Locale::ctype= we may miss some important feedback. You mean setters should raise an exception on error? #include #include "ruby.h" static VALUE rb_setlocale(int category, const char *locale) { char *r = setlocale(category, locale); if (!r) rb_raise(rb_eRuntimeError, "setlocale"); return rb_str_new2(r); } static inline VALUE locale_set(int category, VALUE locale) { return rb_setlocale(category, StringValueCStr(locale)); } static inline VALUE locale_get(int category) { return rb_setlocale(category, NULL); } #define funcs(n, c) \ static VALUE rb_getlocale_##n(VALUE self) {return locale_get(c);} \ static VALUE rb_setlocale_##n(VALUE self, VALUE val) {return locale_set(c, val);} \ /* end of funcs */ foreach_categories(funcs) void Init_locale(void) { VALUE locale = rb_define_module("Locale"); #define methods(n, c) \ rb_define_singleton_method(locale, #n, rb_getlocale_##n, 0); \ rb_define_singleton_method(locale, #n"=", rb_setlocale_##n, 1); \ /* end of methods */ foreach_categories(methods); } -- Nobu Nakada