Skip to content

Commit

Permalink
Fixed bugs in new :: behavior, also documented it in the man page and…
Browse files Browse the repository at this point in the history
… in the NEWS.md. All tests pass, and site has been rebuilt for this 7.0.5
  • Loading branch information
ncondits3 committed Sep 11, 2024
1 parent 7c6bbe1 commit a7068e8
Show file tree
Hide file tree
Showing 316 changed files with 3,955 additions and 3,879 deletions.
50 changes: 50 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
# humdrumR 7.0.5

Version 7.0.5 includes a small patch to fix a bug related to the `::` function, as well as a new feature/behavior which builds off of that fix.


In previous versions, an error would occur if you used `::` inside any of the fundamental humdrumR "with/within" methods (including `base` functions and `dplyr` "verbs").
We've fixed this bug.

----

We've also added a new feature; specifically, we've made using `::` in humdrumR less necessary.
Now, within a humdrumR call to any of these methods (listed below), if you use any function exported by humdrumR, humdrumR will automatically use the humdrumR version of that function, even if another package you have attached includes a function with same name.
In other words, the humdrumR namespace will always takes priority within a humdrumR method call.

For example, the `dplyr` package exports a function called `lag()` and so does humdrumR (these functions do the same thing, but humdrumR's version has a few extra features).
Before this update, if you loaded `dplyr` *after* you loaded humdrumR, then `dplyr`'s `lag()` function would generally take priority over humdrumR's `lag()`.
So, code like this

```
library(humdrumR)
library(dplyr)
readHumdrum(humdrumRroot, 'HumdrumData/BachChorales/.*krn') -> chorales
chorales |> mutate(Lagged = lag(Token))
```

would call `dplyr::lag()`.
This sort of behavior can be confusing but wouldn't normally be the end of the world (this is how R is supposed to work, after all).
However, the `lag()` function is particularly problematic because *many* humdrumR methods rely on our special version of `lag()`.
This is why we've implemented a change:
Now, if you use `lag()` within a humdrumR with/within method, it will default to using the humdrumR version, regardless of what other packages are loaded.
So the code above would use `humdrumR::lag()`.
If you *want* to use `dplyr`'s version (or any other package), you still can by specifying (for example) `dplyr::lag()`.
Another function which (in the past) could lead to frequent namespace confusion was `transpose()`---now, you can safely use `transpose()` and know that your system will use `humdrumR::transpose()`.


All `.humdrumR` methods for the following functions are affected by this change:

+ `with()`
+ `within()`
+ `mutate()`
+ `reframe()`
+ `summarize()`
+ `filter()`
+ `subset()`


# humdrumR 7.0.3

### count() and table()
Expand Down
4 changes: 2 additions & 2 deletions R/Dispatch.R
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ memoizeParse <- function(args, ..., dispatchArgs = c(), minMemoize = 100L, memoi

if (is.struct(result)) {
uniqueArgs$i <- seq_len(nrow(uniqueArgs))
result[merge(memoizeArgs, uniqueArgs, on = colnames(uniqueArgs), sort = FALSE)$i]
result[merge(memoizeArgs, uniqueArgs, sort = FALSE)$i]

} else {
uniqueArgs[ , Result := result]
merge(memoizeArgs, uniqueArgs, on = head(colnames(uniqueArgs), -1), sort = FALSE)$Result
merge(memoizeArgs, uniqueArgs, by = head(colnames(uniqueArgs), -1), sort = FALSE)$Result

}

Expand Down
26 changes: 21 additions & 5 deletions R/Within.R
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@
#' If multiple expression arguments are provided, each expression is evaluated in order, from left to right.
#' Each expression can refer variables assigned in the previous expression (examples below).
#'
#' *Note*: Within any of these expressions, the humdrumR namespace takes priority.
#' This means that, for example, if you use `lag()` within an expression, the humdrumR version of `lag()`
#' will be used, even if you have loaded other packages which have their own `lag()` function.
#' To use another package's function, you'll have to specify `package::function()`---for example, `dplyr::lag()`.
#' This is only an issue when functions have the exact same name as a humdrumR function.
#'
#' ### Expression pre-processing
#'
#' These functions all do some
Expand Down Expand Up @@ -801,15 +807,21 @@ unformula <- function(quosures) {


quoForceHumdrumRcalls <- function(quosures) {
# this changes any function call from a humdrumR function to humdrumR::function
humdrumRpackage <- ls('package:humdrumR')
# this changes any function call from a humdrumR function to humdrumR:::function
# we use ::: because the ls() output includes methods that aren't actually exported (:: won't work).
# we don't include infix functions line %~%

humdrumRpackage <- ls('package:humdrumR') |> grep(pattern = '%', x = _, value = TRUE, invert = TRUE)
humdrumRpackage <- setdiff(humdrumRpackage, 'count')
# we can't do it to count because the count() generic was originally exported by dplyr
# there might other functions which need to be added to this list?

lapply(quosures,
\(quo) {
withinExpression(quo,
predicate = \(Head) Head[1] %in% humdrumRpackage,
func = \(exprA) {
exprA$Head <- paste0('humdrumR::', exprA$Head)
exprA$Head <- paste0('humdrumR:::', exprA$Head)
exprA
})
})
Expand Down Expand Up @@ -1036,9 +1048,13 @@ activateQuo <- function(funcQuosure, dotField) {


autoArgsQuo <- function(funcQuosure, fields) {
predicate <- \(Head) Head %in% c(autoArgTable$Function, paste0(autoArgTable$Function, '.default'))

funcRegex <- paste0('^(humdrumR:::?)?', autoArgTable$Function, '(\\.default)?$')

predicate <- \(Head) any(stringr::str_detect(Head, funcRegex))

do <- \(exprA) {
tab <- autoArgTable[(Function == exprA$Head | paste0(Function, '.default') == exprA$Head) &
tab <- autoArgTable[stringr::str_detect(exprA$Head, funcRegex) &
!Argument %in% names(exprA$Args) &
sapply(Expression, \(expr) length(namesInExpr(fields, expr)) > 0L)]
args <- setNames(tab$Expression, tab$Argument)
Expand Down
1 change: 0 additions & 1 deletion R/humdrumR-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ autoArgTable <- rbind(data.table(Argument = 'groupby', Type = 'melodic',
Expression = list(quote(Tandem)))
)

autoArgTable[, Function := paste0('humdrumR::', Function)]

setOldClass('quosure')
setOldClass('quosures')
Expand Down
16 changes: 7 additions & 9 deletions docs/404.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a7068e8

Please sign in to comment.