+
+sub _localize_error_str {
+ # Find the translation for the R error strings. Internationalization is
+ # present in R >=2.1, with Natural Language Support enabled.
+ my ($self) = @_;
+ my @strings;
+ for my $error_str ($ERROR_STR_1, $ERROR_STR_2) {
+ my $cmd = qq`write(ngettext(1, "$error_str", "", domain="R"), stdout())`;
+ $self->set('cmd', $cmd);
+ # Try to translate string, return '' if not possible
+ my $str = $self->run(q`tryCatch( eval(parse(text=cmd)) , error=function(e){write("",stdout())} )`);
+ $str ||= $error_str;
+ push @strings, $str;
+ }
+ ($ERROR_STR_1, $ERROR_STR_2) = @strings;
+ return 1;
+}
+
+
+sub DESTROY {
+ # The bridge to R is not automatically bombed when Statistics::R instances
+ # get out of scope. Do it now (unless running in shared mode)!
+ my ($self) = @_;
+ if (not $self->is_shared) {
+ $self->stop;
+ }
+}
+
+
+#---------- HELPER SUBS -------------------------------------------------------#
+
+
+sub _trim {
+ # Remove flanking whitespaces
+ my ($str) = @_;
+ $str =~ s{^\s+}{};
+ $str =~ s{\s+$}{};
+ return $str;
+}
+
+
+sub _quote {
+ # Quote a string for use in R. We use double-quotes because the documentation
+ # Quotes {base} R documentation states that this is preferred over single-
+ # quotes. Double-quotes inside the string are escaped.
+ my ($str) = @_;
+ # Escape " by \" , \" by \\\" , ...
+ $str =~ s/ (\\*) " / '\\' x (2*length($1)+1) . '"' /egx;
+ # Surround by "
+ $str = qq("$str");
+ return $str;
+}
+
+
+sub _unquote {
+ # Opposite of _quote
+ my ($str) = @_;
+ # Remove surrounding "
+ $str =~ s{^"}{};
+ $str =~ s{"$}{};
+ # Interpolate (de-escape) \\\" to \" , \" to " , ...
+ $str =~ s/ ((?:\\\\)*) \\ " / '\\' x (length($1)*0.5) . '"' /egx;
+ return $str;