Skip to content

Commit

Permalink
fix issue 1344 (not 1144) with a check in keyword processing (#1370)
Browse files Browse the repository at this point in the history
* fix issue 1144 with a check in keyword processing

* add testing for new getParam check
  • Loading branch information
paciorek authored Dec 17, 2023
1 parent 0b7577d commit 02974fd
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/nimble/R/nimbleFunction_keywordProcessing.R
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,15 @@ getParam_keywordInfo <- keywordInfoClass(

if(isCodeArgBlank(code, 'param'))
stop("'param' argument missing from 'getParam', with no accessor argument supplied")

## Avoid situations where user has syntax from run code in `param` or of getting anything from global env (issue 1344).
paramVars <- all.vars(code$param)
wh <- which(!paramVars %in% nfProc$setupSymTab$getSymbolNames())
if(length(wh))
stop("`param` argument in `getParam` contains variables not found in setup code: ", paste(paramVars[wh], collapse = ", "), ".")

paramInfo_ArgList <- list(model = code$model, node = nodeFunVec_ArgList$nodes, param = code$param, hasIndex = useNodeFunctionVectorByIndex) ## use nodeFunVec_ArgList$nodes instead of code$node because nodeFunVec_ArgList$nodes may have been updated if code$nodes has a run-time index. In that case the paramID will be vector

paramInfoName <- paramInfo_SetupTemplate$makeName(paramInfo_ArgList)
paramIDname <- paramInfo_SetupTemplate$makeOtherNames(paramInfoName, paramInfo_ArgList)

Expand Down
46 changes: 46 additions & 0 deletions packages/nimble/tests/testthat/test-getParam.R
Original file line number Diff line number Diff line change
Expand Up @@ -300,5 +300,51 @@ test_that("getParam works in various multi-instance combinations", {
expect_identical(gsp5_2$run(), cgsp5$gsp5_2$run())
})

test_that("error trap indexing in param argument of getParam", {

nf <- nimbleFunction(
setup = function(model) {
i <- 2
params <- c('mean','sd')
},
run = function() {
returnType(double(0))
tmp <- model$getParam('y', params[i])
return(tmp)
})

code <- nimbleCode({
y ~ dnorm(0, 1)
})
m <- nimbleModel(code)
rnf <- nf(m)
cm <- compileNimble(m)
## Should succeed as `i` in setup.
cnf <- compileNimble(rnf, project = m)

# or i in global; or i in run
nf <- nimbleFunction(
setup = function(model) {
params <- c('mean','sd')
},
run = function() {
i <- 2
returnType(double(0))
tmp <- model$getParam('y', params[i])
return(tmp)
})

code <- nimbleCode({
y ~ dnorm(0, 1)
})
m <- nimbleModel(code)
rnf <- nf(m)
cm <- compileNimble(m)
expect_error(cnf <- compileNimble(rnf, project = m),
"contains variables not found in setup")

})


options(warn = RwarnLevel)
nimbleOptions(verbose = nimbleVerboseSetting)

0 comments on commit 02974fd

Please sign in to comment.