Closed serkor1 closed 3 months ago
No objection to this, especially after seeing that {cli} is nice and lightweight with no non-base R dependencies. No time in near future to implement for me I'm afraid though.
It should be simple to implement - if there is consensus on using it, I could make a PR during the weekend.
What is your release schedule? Could this update alongside the recent fix I made justify a CRAN update?
I have a private repo that depends on {calendar} 😁
Happy to be a concensus of one on this, yes please @serkor1 !
What is your release schedule? Could this update alongside the recent fix I made justify a CRAN update?
Release schedule: when the CRAN team gets back from holiday on 17th August, for sure!
Feel free to add your name to the DESCRIPTION also :pray:
@Robinlovelace is there any reason you are using the methods::is()
- instead of the inherits()
-function?
@Robinlovelace is there any reason you are using the
methods::is()
- instead of theinherits()
-function?
methods::is()
is what I've seen in other packages, happy to use inherits()
if there are advantages of that.
As what I can tell from the files you don't use the package for anything other than verifying classes, so I think we could get rid of the dependency. There is no advantage to it other than reducing dependencies as far as I know!
{methods} is part of base R so no additional dep, right?
This is my understanding, yes. It doesn't have any dependencies (I think). But if you remove it from Imports
in the description
-file, you'll get the following error:
❯ checking dependencies in R code ... WARNING
'::' or ':::' imports not declared from:
‘methods’
This is what I was referring to when I said "we could get rid of the dependency"!
No objections to getting rid of it. However, it's a 'hypothetical dependency' because most R installation already have {methods}.
Regarding {cli} and messaging, @maelle and I wrote this blog post with some (in our opinion) good recommendations.
Hi,
I was wondering wether there is any interest in using the {cli}-package for error-messages and handling. In my own package {cryptoQuotes} I use a high-level wrapper to assert the argument values, which returns a detailed and formatted error-message.
The function can be seen below, and I have created a MWE for demonstration.
Function
``` r # assert function assert <- function( ..., error_message = NULL) { # 1) count number of expressions # in the ellipsis - this # is the basis for the error-handling number_expressions <- ...length() named_expressions <- ...names() # 2) if there is more than # one expression the condtions # will either be stored in an list # or pased directly into the tryCatch/stopifnot if (number_expressions != 1 & !is.null(named_expressions)){ # 2.1) store all conditions # in a list alongside its # names conditions <- c(...) # 2.2) if !is.null(condition_names) the # above condition never gets evaluated and # stopped otherwise, if there is errors # # The condition is the names(list()), and is # the error messages written on lhs of the the assert # function if (all(conditions)) { # Stop the funciton # here if all conditions # are [TRUE] return(NULL) } else { cli::cli_abort( message = c( "x" = named_expressions[which.min(conditions)] ), call = sys.call( 1 - length(sys.calls()) ) ) } } # 3) if there length(...) == 1 then # above will not run, and stopped if anything tryCatch( expr = { eval.parent( substitute( stopifnot(exprs = ...) ) ) }, error = function(error){ # each error message # has a message and call # # the call will reference the caller # by default, so we need the second # topmost caller cli::cli_abort( # 3.1) if the length of expressions # is >1, then then the error message # is forced to be the internal otherwise # the assert function will throw the same error-message # for any error. message = if (is.null(error_message) || number_expressions != 1) error$message else error_message, call = sys.call( 1 - length(sys.calls()) ) ) } ) } ```Demonstration of the
assert()
-functionThe function itself a bit awkward, but it works like a charm (if you ask me :laughing:). Below is a simple function,
foo
, which returns thesum
but checks whether the argumenta
is anumeric
-value. I think that such a helper-function would be nice to have in the high-level functions as theic_dataframe()
-function.Created on 2024-08-08 with reprex v2.1.0
Overhead
However, the
assert()
-function has a huge overhead cost on computation. See the comparison below against a function,bar()
, that usesstopifnot()
instead,Benchmark
So it should only be considered if you believe your end-user would benefit from it!