From b646a17079555cc3fa6dadf4d2120adbb039f297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bojanowski?= Date: Thu, 17 Sep 2026 13:56:45 +0200 Subject: [PATCH] match_names(partial = FALSE) no longer uses a non-UTF-8 sentinel string. The literal "\n\xf5\xdc\n" is invalid UTF-8 and unmarked, so when the package was installed in a UTF-8 locale and then loaded in a C locale (e.g., on stripped-down HPC compute nodes), unserializing the function from the lazy-load DB produced "strings not representable in native encoding" and "cannot be translated to UTF-8" warnings. Since pmatch() assigns all exact matches (sequentially) before attempting any partial ones, discarding the non-exact assignments afterwards gives exactly the result the sentinel was emulating. Fixes #44. --- NEWS.md | 6 ++++++ R/misc.utilities.R | 12 +++++------- man/match_names.Rd | 5 ----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/NEWS.md b/NEWS.md index 848f49d..785e24e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# statnet.common 4.14.0 + +## Bug fixes + +* `match_names(partial = FALSE)` no longer embeds a non-UTF-8 sentinel string, which produced "strings not representable in native encoding" warnings when the package was installed in a UTF-8 locale and loaded in a C locale. (#44; originally reported against the `ergm` progress bars) + # statnet.common 4.13.0 ## New utilities diff --git a/R/misc.utilities.R b/R/misc.utilities.R index 805ef91..070d776 100644 --- a/R/misc.utilities.R +++ b/R/misc.utilities.R @@ -83,10 +83,6 @@ vector.namesmatch<-function(v,names,errname=NULL){ #' #' * There is ambiguity that [pmatch()] cannot resolve. #' -#' @note At this time, passing `partial=FALSE` will use a crude -#' sentinel to prevent partial matching, which in some, extremely -#' improbable, circumstances might not work. -#' #' @param v a vector #' @param names a character vector of element names #' @param default value to be used for elements of `names` not found in `v` @@ -168,9 +164,11 @@ match_names <- function(v, names, default = NULL, partial = TRUE, errname = NULL v <- v[!blanks] } - # partial == FALSE -> add a sentinel string at the end of all strings to prevent partial matching. - namesmatch <- if(partial) pmatch(names(v), names) - else pmatch(paste(names(v), "\n\xf5\xdc\n"), paste(names, "\n\xf5\xdc\n")) + namesmatch <- pmatch(names(v), names) + # partial == FALSE -> keep only the exact matches. pmatch() assigns all + # exact matches before attempting any partial ones, so this leaves + # exactly the sequential exact matches. + if(!partial) namesmatch[which(names[namesmatch] != names(v))] <- NA used <- !is.na(namesmatch) found <- unwhich(na.omit(namesmatch), length(names)) diff --git a/man/match_names.Rd b/man/match_names.Rd index d845e14..5e912cd 100644 --- a/man/match_names.Rd +++ b/man/match_names.Rd @@ -57,11 +57,6 @@ no default is specified. \item There is ambiguity that \code{\link[=pmatch]{pmatch()}} cannot resolve. } } -\note{ -At this time, passing \code{partial=FALSE} will use a crude -sentinel to prevent partial matching, which in some, extremely -improbable, circumstances might not work. -} \examples{ # Unnamed: