gargoyle
gargoyle copied to clipboard
Warning: Error in watch: could not find function "watch"
Hi @ColinFay ,
Thank you so much for {gargoyle}. A colleague of mine and I have been implementing it a lot.
Once in a while , I get this error when I launch the app for the first time. Do you know why? We've initiated, triggered and watched (through gargoyle::on()) our events correctly but still.
Hi,
I also had the same problem. Restarting the session and/or emptying the environment did not solve the issue. What worked was to load {gargoyle}
in R/run_app.R
. Hope that helps @Shelmith-Kariuki
Best,
Hi @cpauvert and @Shelmith-Kariuki
Actually you are diagnosing the problem correctly, I think, in that the watch
function cannot (always) be found.
For this neither emptying the environment nor restarting the session helps because your R
session will still not know the function watch()
. Solutions:
- If you call
library(gargoyle)
before, then youR
session is aware of thewatch
function. However this is not recommended because there can be several possiblewatch
functions, for example the package{testthat}
also has awatch
function; if you first dolibrary(gargoyle)
and then dolibrary(testthat)
and have anR
script withwatch()
your code will use thewatch
from the lastlibrary(testthat)
! Look at the following example
watch
#> Error in eval(expr, envir, enclos): object 'watch' not found
library(gargoyle)
watch
#> function(name, session = getDefaultReactiveDomain()) {
#> session$userData[[name]]()
#> }
#> <bytecode: 0x55b4ec6c66b0>
#> <environment: namespace:gargoyle>
library(testthat)
#>
#> Attaching package: 'testthat'
#> The following object is masked from 'package:gargoyle':
#>
#> watch
watch
#> function (path, callback, pattern = NULL, hash = TRUE)
#> {
#> prev <- dir_state(path, pattern, hash = hash)
#> repeat {
#> Sys.sleep(1)
#> curr <- dir_state(path, pattern, hash = hash)
#> changes <- compare_state(prev, curr)
#> if (changes$n > 0) {
#> keep_going <- TRUE
#> try(keep_going <- callback(changes$added, changes$deleted,
#> changes$modified))
#> if (!isTRUE(keep_going))
#> return(invisible())
#> }
#> else {
#> }
#> prev <- curr
#> }
#> }
#> <bytecode: 0x55b4ecb93fe0>
#> <environment: namespace:testthat>
- Therefor, one recommended way (see e.g. https://r-pkgs.org/dependencies-in-practice.html#sec-dependencies-in-imports-r-code), if you are working inside a package like
{golem}
, is to always prefix the function (which works also withoutlibrary(gargoyle)
andlibrary(testthat)
so try to write
watch
#> Error in eval(expr, envir, enclos): object 'watch' not found
gargoyle::watch
#> function(name, session = getDefaultReactiveDomain()) {
#> session$userData[[name]]()
#> }
#> <bytecode: 0x5636015371a0>
#> <environment: namespace:gargoyle>
testthat::watch
#> function (path, callback, pattern = NULL, hash = TRUE)
#> {
#> prev <- dir_state(path, pattern, hash = hash)
#> repeat {
#> Sys.sleep(1)
#> curr <- dir_state(path, pattern, hash = hash)
#> changes <- compare_state(prev, curr)
#> if (changes$n > 0) {
#> keep_going <- TRUE
#> try(keep_going <- callback(changes$added, changes$deleted,
#> changes$modified))
#> if (!isTRUE(keep_going))
#> return(invisible())
#> }
#> else {
#> }
#> prev <- curr
#> }
#> }
#> <bytecode: 0x563601998670>
#> <environment: namespace:testthat>
instead of watch
. This way you can also refer to testthat::watch()
, and then to gargoyle::watch()
or other watch()
-functions without ambiguity, whenever you want.
Thank you @ilyaZar for your extensive answer! I also directly thought of this, but the issue is that at this stage of the project I was not even calling gargoyle::watch()
but only gargoyle::on()
, similarly to @Shelmith-Kariuki apparently.
This is why I was surprised that the error message was
Warning: Error in watch: could not find function "watch"
but I could not traceback from where.
Maybe gargoyle::on()`` uses
watch()` somewhere without the canonical prefix?
If you have any lead, they would be most welcome!
Actually not that I am aware of:
here is the code snippet related to the part which the function on()
uses:
https://github.com/ColinFay/gargoyle/blob/83234de417b9b0b39be9b8f1556e5df1968624b2/R/funs.R#L138-L148
The substitute call does generate an internal gargoyle::watch()
for the observeEvent
.
The full on()
function is like so:
https://github.com/ColinFay/gargoyle/blob/83234de417b9b0b39be9b8f1556e5df1968624b2/R/funs.R#L124-L149
It's a bit strange... By the way the full link to the file so you can check yourself https://github.com/ColinFay/gargoyle/blob/master/R/funs.R
Maybe you are changing the "session"? Currently the session parameter is not passed directly down from on
to watch
, see the issue #17 (solved by #18 ). This session
-error went probably unnoticed for quite a while since one almost always is not changing the session.
You are having your App as a repo: could you start in a fresh R session? Maybe (probably you are already doing this but still):
call
golem::run_dev()
because it recompiles your package. Maybe some of the watch()
instances you changed to gargoyle::watch()
are not having the change yet in the compiled package version.
Yep, was also looking! Thanks! BUT this dates https://github.com/ColinFay/gargoyle/commit/17423812fe166ab5e990ea0b432d76b17c8875b8 back to after the package was on the CRAN, and this is the version I installed. Trying out with the dev version now..
EDIT: yes this did the trick!
ah that could be it :)
Checking again that :
gargoyle::on
did correctly have the prefix! :+1: and if yes, I also then added {gargoyle}
as a remote dependency to be sure in the future:
usethis::use_dev_package("gargoyle", remote = "ColinFay/gargoyle")
I had this error with current versions. No watch
statements so must be called internally (I had one on
call which when removed also removed the error...)
Solved by adding @import gargoyle
to the app_server.R script so gargoyle
is always loaded and watch
therefore found.