Hi,
At Sun, 7 Jun 2009 00:24:55 +0900,
Adam S. 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 <stdio.h> 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 <locale.h>
#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®;
}
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©;}
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);
}