From: Nobuyoshi Nakada Date: 2009-06-06T23:23:18+09:00 Subject: Re: Iconv and incompatible encodings Hi, At Thu, 4 Jun 2009 00:28:25 +0900, Adam Strzelecki wrote in [ruby-talk:338275]: > Alternative and light solution is to create own extension as below: First of all, option after // is GNU iconv local extension. Second, extconf.rb must check for the necessary header, and whether each categories are defined. # extconf.rb require 'mkmf' extension_name = 'locale' header = "locale.h" dir_config(extension_name) if have_header(header) lc = %w[CTYPE NUMERIC TIME COLLATE MONETARY MESSAGES ALL] lc = lc.delete_if {|n| !have_macro("LC_#{n}", header)}. collect {|n| "def(#{n.downcase}, LC_#{n})"}. join(' ') $defs << "-Dforeach_categories(def)=\"#{lc}\"" create_header create_makefile(extension_name) end Next, StringValueCStr() is much better than Check_Type(). > ... and use: > require 'locale' > Locale::setlocale Locale::LC_CTYPE, '' And it feels too redundant. I guess Locale.ctype = '' would be easy. /* locale.c */ #include #include "ruby.h" static VALUE rb_setlocale(int category, VALUE locale) { char *r = setlocale(category, StringValueCStr(locale)); return r ? rb_str_new2(r) : Qnil; } static VALUE rb_getlocale(int category) { char *r = setlocale(category, NULL); return r ? rb_str_new2(r) : Qnil; } #define funcs(n, c) \ static VALUE rb_getlocale_##n(VALUE self) {return rb_getlocale(c);} \ static VALUE rb_setlocale_##n(VALUE self, VALUE val) {return rb_setlocale(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