Within a function, I want to change the locale, do some stuff, then unchange it. Because side effects are bad.
old_locale <- Sys.getlocale()
# do some stuff
Sys.setlocale(old_locale)
However, Sys.setlocale
requires a category
and locale
argument.
On the other hand, Sys.getlocale()
gives me this:
"LC_COLLATE=English_Australia.1252;LC_CTYPE=English_Australia.1252;LC_MONETARY=English_Australia.1252;LC_NUMERIC=C;LC_TIME=English_Australia.1252"
Ok. I can probably deal with this:
old_locale <- Sys.getlocale()
locale_key_values <- strsplit(strsplit(old_locale, ';')[[1]], '=')[[1]], '=')
locale_keys <- lapply(locale_key_values, getElement, name=1)
locale_values <- lapply(locale_key_values, getElement, name=2)
# do some stuff
mapply(Sys.setlocale, category=locale_keys, locale=locale_values)
Problem solved!
...or is it?
Sys.setlocale(locale='C')
Sys.getlocale()
now returns "C"
! That's not going to work with my key-value parser above.
And I suddenly realise that I don't know anything about locales or the range of strings that Sys.getlocale()
might return.
Does anyone know of a reliable way to save and restore locale state?
?Sys.getlocale
says:
For
category = "LC_ALL"
the details of the string are system-specific: it might be a single locale name or a set of locale names separated by"/"
(Solaris, OS X) or";"
(Windows, Linux). For portability, it is best to query categories individually: it is not necessarily the case that the result offoo <- Sys.getlocale()
can be used inSys.setlocale("LC_ALL", locale = foo)
.
So you need to do something like:
localeCategories <- c("LC_COLLATE","LC_CTYPE","LC_MONETARY","LC_NUMERIC","LC_TIME")
locales <- setNames(lapply(localeCategories, Sys.getlocale), localeCategories)
Better yet, you should determine which locale setting(s) you need to change, and only change the one(s) you need to. For example, you might only need to change LC_TIME if you're parsing date-time character strings, or you might only need to change LC_COLLATE if you need to change the character string collation order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With