Giter Club home page Giter Club logo

glue's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

glue's Issues

Scoping issue

First of all, thanks for this great package! I'm migrating some of my internal R pkg functions from sprintf, but found some scoping issues and decided to ask for some help here. I'm pretty sure it's not glue related, rather just PEBKAC on my end, but cannot figure out what's the problem.

Example code:

lapply(1:2, function(x) glue::glue('{x * 2}'))
#> [[1]]
#> 2
#> 
#> [[2]]
#> 4

Trying to use this with a helper function:

f <- function(msg) {
    glue::glue(msg)
}
lapply(1:2, function(x) f('{x * 2}'))
#> Error in eval(x, envir = envir): object 'x' not found

Then trying to specify the parent frame:

f <- function(msg) {
    glue::glue(msg, .envir = parent.frame())
}
lapply(1:2, function(x) f('{x * 2}'))
#> Error in eval(x, envir = envir): object 'msg' not found

So now it's evaluated in the parent frame, but looking for msg instead of x defined withing msg.

I tried a couple of other things eg

f <- function(msg) {
    eval.parent(glue::glue(msg))
}
lapply(1:2, function(x) f('{x * 2}'))
#> Error in eval(x, envir = envir): object 'x' not found

But did not figure this out. Any suggestions?

Should there be an `unglue()`?

unglue() so you could see the generalized form of whatever specific string that was made with glue().

Simple form would be something like:

library(glue)

unglue <- function(x) {
    stopifnot(inherits(x, "glue"))
    attr(x, "glue_string")
}

glue_string <- "echo '{saywhat}'"
x <- glue(glue_string, saywhat = "hello world")
attr(x, "glue_string") <- glue_string
str(x)
#> Class 'glue'  atomic [1:1] echo 'hello world'
#>   ..- attr(*, "glue_string")= chr "echo '{saywhat}'"

x
#> echo 'hello world'
unglue(x)
#> [1] "echo '{saywhat}'"

Ambitious form would also extract out the value of the inputs

unglue_ambitious(x)
#> [1] "echo '{saywhat}'"
#>  ..- attr(*, "saywhat")= chr "hello world"

.envir should accept anything that can be coerced to an environment.

Sometimes you have the values that you want to interpolate in a list (example: the params object in an Rmarkdown file), and you want to interpolate using these values. Currently, you must manually convert this to an environment in order to do so using glue, but it would be nice if the function would do it for you.

Example:

# using named args
glue("Hello {firstname} {lastname}", firstname="John", lastname="Doe")


person <- c(firstname="John", lastname="Doe")
# Trying to pass a named vector as .envir doesn't workglue("Hello {firstname} {lastname}", .envir=person)
# Must do this instead
glue("Hello {firstname} {lastname}", .envir=as.environment(as.list(person)))

The .envir arg should probably satisfy rlang::is_dictionary if it isn't an environment.

Mechanism for inserting literal braces

E.g something like:

f('my name is {name}, but do not \\{messwiththis\\}')

or (better since less typing and also concordant with what Python does):

f('my name is {name}, but do not {{messwiththis}}')

wherein the {{ would get replaced by {.

Happy to help with PR if you want help.

Removing leading spaces

Great feature! I was wondering if it should happen before the command substitution. Because right now I get:

l <- list(a = list(a1 = 1, a2 = 2, a3 = 3), b = "foo")
cat(yaml::as.yaml(l))
#> a:
#>   a1: 1.0
#>   a2: 2.0
#>   a3: 3.0
#> b: foo
glue("
  # Indented a bit in the code, but not in the output
  { yaml::as.yaml(l) }
")
#> # Indented a bit in the code, but not in the output
#> a:
#> a1: 1.0
#> a2: 2.0
#> a3: 3.0
#> b: foo

Bump version?

Would you be willing to bump past the CRAN version? I'm using things that were added since then and want to capture that in DESCRIPTION. I already have glue in Remotes but feel like I should also state that version must be greater than 1.0.0.

Installation error

install.packages("devtools")
trying URL 'https://mirrors.ebi.ac.uk/CRAN/bin/windows/contrib/3.4/devtools_1.13.2.zip'
Content type 'application/zip' length 442517 bytes (432 KB)
downloaded 432 KB

package 'devtools' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
C:\Users\edguevara\AppData\Local\Temp\Rtmp4gSnoj\downloaded_packages

library(tidyverse)
Error: package or namespace load failed for 'tidyverse' in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCh
eck = vI[[j]]):
there is no package called 'glue'
devtools::install_github("tidyverse/glue")
Downloading GitHub repo tidyverse/glue@master
from URL https://api.github.com/repos/tidyverse/glue/zipball/master
Error: running command '"C:/PROGRA1/R/R-341.0/bin/x64/R" --no-site-file --no-environ --no-save --no-restore --quiet CMD
config CC' had status 1

collapse() when x has length zero

It feels like collapse() would be more consistent with glue() (and more convenient) if it returned character(0) if the input has length zero.

library(glue)
glue("{x}", x = "hi")
#> hi
glue("{x}", x = character(0))
#> character(0)
collapse(x = c("hi", "bye"), last = " and ")
#> [1] "hi and bye"
collapse(x = c(NULL, "bye"), last = " and ")
#> [1] "bye"
collapse(x = c("hi", NULL), last = " and ")
#> [1] "hi"
collapse(x = NULL, last = " and ")
#> [1] ""
collapse(x = character(), last = " and ")
#> [1] ""

CRAN Release

Hi, thanks for providing a great package.
Do you have any plan in mind to release this fstrings library on CRAN?
I'm thinking about importing your library in my library.

Inconsistent handling of NULL expressions

When any expression (but the last) is NULL then glue returns an empty character vector. In case the last expression is NULL it ignores the last expressions and returns the result of the other expressions.

library(glue)

empty <- c()
glue(empty, 1)
glue(1, empty)
#> 1
glue(1, 2, empty)
#> 12
glue(1, empty, 0)

glue("{empty}", 1)
glue(1, "{empty}")
glue(1, "{empty}", 0)

glue_sql

A version of glue() that automatically quotes results, useful for constructing SQL queries.

Hard-to-predict whitespace trimming

I'm trying to use glue to make bulleted lists for messages. I'm a bit puzzled. Maybe this is #47?

I don't understand why I lose the two spaces before the asterisk, as it's not leading whitepace of the first line.

glue::glue("The stuff before the bullet list
              * one bullet")
#> The stuff before the bullet list
#> * one bullet

Adding a new line at the start helps, but I'm not sure why, because now the bulleted line is the 3rd (and last) line.

glue::glue("
           The stuff before the bullet list
             * one bullet")
#> The stuff before the bullet list
#>   * one bullet

Adding a new line to the end doesn't help, but I though it might, because it makes my bulleted line NOT the last line.

glue::glue("The stuff before the bullet list
              * one bullet
           ")
#> The stuff before the bullet list
#> * one bullet

glue() inside mutate()

I would like to do

iris %>% mutate(glued_stuff = glue("This {Species} has a petal length of {Petal.Length}"))

instead of

iris %>% mutate(glued_stuff = glue_data(., "This {Species} has a petal length of {Petal.Length}"))

What do you think about this?

`glue()` and `rlang::quo_name()` unexpected interaction

I apologize in advance if this is me not understanding how to use these tools appropriately. But the intention is to have a nicer replacement to paste0("sth_", quo_name(expr) because when it is more complicated than just a prefix or suffix paste/0 is hella ugly and to read.

setup

library(rlang)
library(glue)

glue + rlang = 😞

glue_quo <- function(expr) {
    expr <- enquo(expr)
    glue("expr name is {expr}", quo_name(expr))
}
glue_quo(expr = 3)
#> expr name is ~3
#> expr name is 33

session info

devtools::session_info()
#> Session info -------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.4.0 (2017-04-21)
#>  system   x86_64, darwin15.6.0        
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_CA.UTF-8                 
#>  tz       America/Vancouver           
#>  date     2017-05-20
#> Packages -----------------------------------------------------------------
#>  package   * version    date       source                          
#>  backports   1.0.5      2017-01-18 CRAN (R 3.4.0)                  
#>  base      * 3.4.0      2017-04-21 local                           
#>  compiler    3.4.0      2017-04-21 local                           
#>  datasets  * 3.4.0      2017-04-21 local                           
#>  devtools    1.13.1     2017-05-13 CRAN (R 3.4.0)                  
#>  digest      0.6.12     2017-01-27 CRAN (R 3.4.0)                  
#>  evaluate    0.10       2016-10-11 CRAN (R 3.4.0)                  
#>  glue      * 1.0.0      2017-05-21 Github (tidyverse/glue@41a5cff) 
#>  graphics  * 3.4.0      2017-04-21 local                           
#>  grDevices * 3.4.0      2017-04-21 local                           
#>  htmltools   0.3.6      2017-04-28 CRAN (R 3.4.0)                  
#>  knitr       1.15.20    2017-05-02 Github (yihui/knitr@f3a490b)    
#>  magrittr    1.5        2014-11-22 CRAN (R 3.4.0)                  
#>  memoise     1.1.0      2017-04-21 CRAN (R 3.4.0)                  
#>  methods   * 3.4.0      2017-04-21 local                           
#>  Rcpp        0.12.10    2017-03-19 CRAN (R 3.4.0)                  
#>  rlang     * 0.1.1.9000 2017-05-21 Github (tidyverse/rlang@7c2f7e8)
#>  rmarkdown   1.5        2017-04-26 CRAN (R 3.4.0)                  
#>  rprojroot   1.2        2017-01-16 CRAN (R 3.4.0)                  
#>  stats     * 3.4.0      2017-04-21 local                           
#>  stringi     1.1.5      2017-04-07 CRAN (R 3.4.0)                  
#>  stringr     1.2.0      2017-02-18 CRAN (R 3.4.0)                  
#>  tools       3.4.0      2017-04-21 local                           
#>  utils     * 3.4.0      2017-04-21 local                           
#>  withr       1.0.2      2016-06-20 CRAN (R 3.4.0)                  
#>  yaml        2.1.14     2016-11-12 CRAN (R 3.4.0)

Unnamed arguments of length > 1

glue::glue("{1:3}")
#> 1
#> 2
#> 3
glue::glue(1:3)
#> Error: All unnamed arguments must be length 1

Can the two expressions be made equivalent? This will simplify the transition from paste0().

Using newly created local vars

Can we have lst() or tibble() semantics?

glue::glue("{b}", a = 1, b = a)
#> Error in eval(expr, envir, enclos): object 'a' not found

Expected result: "1"

glue_data() ignores .envir when .x is an environment

When the .x argument of glue_data() is an environment, the evaluation of ... takes place in .x and not in .envir, contrary to the documented role of .envir. In particular, if ... is not in .x, then glue_data() will fail.

Is this the intended behavior?

Example:

env <- new.env(parent = baseenv())
env$a <- "This is 'a'"

text <- "{a}"

glue_data(.x = env, text)
## Error in eval(x, envir = data, enclos = envir) : object 'text' not found

glue_data() has not evaluated text in .envir = parent.frame().

Naively, I would expect .x to be used solely for object look-up, i.e., as if .x were coerced to a list:

glue_data(.x = as.list(env), text)
## This is 'a'

Issues with UTF-8 strings

Glue is not working properly with UTF-8 encoded strings.

> x = "pão"
> x
[1] "pão"
> Encoding(x)
[1] "latin1"
> glue("{x}")
pão
> x = enc2utf8("pão")
> x
[1] "pão"
> Encoding(x)
[1] "UTF-8"
> glue("{x}")
pão

Formatters

Are there any plans of adding formatters?

To clarify, by “formatter” I mean (1) an interface and (2) a glue syntax that advanced formatting of glue tokens. Here’s an example:

glue('π = {pi}')
glue('π to two decimal places = {format(pi, digits = 3)}')

With formatters, the second line could be for instance written as

glue('π to two decimal places = {pi:0.2}')

Many libraries offer similar capabilities, for instance composite formatting in .NET.

Ideally this would be extensible, allowing users to register their own formatters. For instance the following is thinkable:

arrgh_glue = function (str, options) {
    gsub('r', 'R', str)
}

# optionally, though ideally not necessary:
#   register_glue_formatter(arrgh = arrgh_glue)

name = 'Konrad'
glue('Hello, {name:arrgh}!')
# Hello, KonRad!

The .NET documentation has some more examples that show the scope of what could be possible.

Evaluate named arguments

e.g.

f(
  'My name is {name},',
  ' my age next year is {age + 1},',
  ' my anniversary is {format(anniversary, "%A, %B %d, %Y")}.',
  name = "Fred",
  age = 50,
  anniversary = as.Date("1991-10-12")
)

String class that automatically cats?

cat_string <- function(x) {
  stopifnot(is.character(x))
  
  structure(x, class = "cat_string")
}

print.cat_string <- function(x, ..., sep = "\n") {
  cat(x, ..., sep = sep)
}

glue_sql is not exported

Running the example for glue_sql in the README throws the error:

Error in glue_sql("\n SELECT {var}\n FROM {tbl}\n WHERE {tbl}.sepal_length > {num}\n AND {tbl}.species = {val}\n ", :
could not find function "glue_sql"

I need to run glue::glue_sql for it to work.

glue of the empty string

Aside from the change in class, glue() acts as the identity function on strings without expressions, except the empty string: glue("") gives character(0).

Is this exception intended?

[feature request] wrapper for error-safe templates

A few years ago I asked this question on SO

http://stackoverflow.com/questions/16595621/error-safe-templating-with-brew-whisker

The problem is summarised as follows: given 1) a template string, 2) a named list of values, insert those values in the template (with evaluation of R code), but return an error if one or more named values are missing. The solutions with brew or whisker were not particularly elegant.

I think glue provides a good alternative, but it would be nice to have a helper function that automatically enables checking of absent values in the environment (and get their name in the error message).

library(glue)
data <- list( name = "Chris", value= 124)
do.call(glue, list('Hello {name} You have just won ${value}!', .envir=as.environment(data)))
# Hello Chris You have just won $124!
do.call(glue, list('Hello {name} You have just won ${value}!', .envir=as.environment(data[-1])))
# Error in eval(expr, envir, enclos) : object 'name' not found

"Inputs are not vectorized" 🤔

Inputs are not vectorized

I'm puzzled by this statement in the main help file. The example mtcars %>% glue_data("{rownames(.)} has {hp} hp") seems to immediately go counter to this (not to mention lots of usage I've made). Can this be reworded so the meaning is more clear?

Corrupt output with leading spaces

Seems glue corrupt the input string with space or tabs at begin.

I tried with CRAN and git version of the package.

devtools::install_github("tidyverse/glue")
cyr <- 2017
period <- 2
rows_limit <- 1000

x <- glue::glue('SELECT MIN_MEAN_QUANTITY_OUT,
                        MIN_MEAN_QUANTITY_IN,
                        MAX_MEAN_PRICE_OUT,
                        MAX_MEAN_PRICE_IN
                   FROM LOAD_BOUNDS_BY_YM_NROWS 
                  WHERE YEAR = {cyr}
                    AND MONTH = {period - 1}
                    AND MIN_NUM_OF_ROWS_PQ = {rows_limit}')
x

Output:

SELECT MIN_MEAN_QUANTITY_OUT,
MIN_MEAN_QUANTITY_IN,
MAX_MEAN_PRICE_OUT,
MAX_MEAN_PRICE_IN
LOAD_BOUNDS_BY_YM_NROWS 
YEAR = 2017
MONTH = 1
MIN_NUM_OF_ROWS_PQ = 1000

FROM WHERE, AND are missing in the result.

Session info:

R version 3.4.0 (2017-04-21)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Arch Linux

Matrix products: default
BLAS: /usr/lib/R/lib/libRblas.so
LAPACK: /usr/lib/R/lib/libRlapack.so

locale:
 [1] LC_CTYPE=ru_RU.UTF-8       LC_NUMERIC=C               LC_TIME=ru_RU.UTF-8        LC_COLLATE=C              
 [5] LC_MONETARY=ru_RU.UTF-8    LC_MESSAGES=ru_RU.UTF-8    LC_PAPER=ru_RU.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=ru_RU.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_3.4.0  tools_3.4.0     parallel_3.4.0  glue_1.1.1.9000

Suppress NAs in `glue::glue()`?

paste0() and sprintf() treat NA_character_ as "NA":

sv = c(809, NA_character_, "help")
paste0(sv, ".io")
#> [1] "809.io"  "NA.io"   "help.io"
sprintf("%s.io", sv)
#> [1] "809.io"  "NA.io"   "help.io"

Not sure if it's intended, but glue::glue() also fails to suppress NA:

glue::glue("{sv}.io")
#> 809.io
#> NA.io
#> help.io

stringr::str_c performs better:

stringr::str_c(sv, ".io")
#> [1] "809.io"  NA        "help.io"

Support vectors of length 0

x <- character()
glue::glue("{x}")
#> Error: Variables must be length 1 or 1

I think this should return an empty character vector.

Escaped Braces Cause Unexpected Input Failure

> f('my name is {name}, but do not \\{messwiththis\\}')
Error in fstring_(x, function(x) paste(collapse = sep, fun(eval(parse(text = x),  : 
  <text>:1:13: unexpected input
1: messwiththis\
                ^

Seems to be an fstrings thing since the following parses fine:

> 'my name is {name}, but do not \\{messwiththis\\}'
[1] "my name is {name}, but do not \\{messwiththis\\}"

Also happy to help if you want help.

Recurring segfaults in CI builds

I have CI set up on gitlab for my package builds. When I started using glue, I get the following segfaults (I am posting the output of all the jobs):

Running with gitlab-ci-multi-runner 1.11.1 (a67a225)
  on dev (9d172ed6)
Using Shell executor...
Running on AnalyticsDevVM...
Fetching changes...
Removing TTdashboard.Rcheck/
Removing TTdashboard_0.2.39.tar.gz
HEAD is now at 538f5eb Merge branch '73-sac-tooltip-missing-total' into 'dev'
Checking out 538f5ebf as dev...
Skipping Git submodules setup
$ awk '{sub(/quick/, "all"); print}' tests/testthat.R > tests/tmp.R
$ mv tests/tmp.R tests/testthat.R
$ R -e "cov<-covr::package_coverage(type='all');print(cov);covr::report(cov,file='index.html',browse=FALSE)"

R version 3.3.2 (2016-10-31) -- "Sincere Pumpkin Patch"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> cov<-covr::package_coverage(type='all');print(cov);covr::report(cov,file='index.html',browse=FALSE)
Error: Failure in `/tmp/RtmpJdZkqe/R_LIBS3d672089871e/TTdashboard/TTdashboard-tests/testthat.Rout.fail`
> library(testthat)
> library(TTdashboard)
> 
> test_check("TTdashboard", filter = "all")

 *** caught segfault ***
address 0x30, cause 'memory not mapped'

Traceback:
 1: .Call(to_impl, unnamed_args, function(expr) as.character(eval2(parse(text = expr),     envir = env, data = .x)))
 2: glue_data(NULL, ..., .sep = .sep, .envir = .envir)
 3: glue::glue("SELECT ScenarioId, {flexcol} CountryId, FactorId, YearId, DataValue\n        FROM {table}\n        USE INDEX ({xbindex})\n        WHERE {fixedcol} = {fixed} AND\n        {specific_col} = {specific_value} AND\n        ScenarioOriginId = {scenario_origin} AND\n        ScenarioId = {globals$scenarioId} AND\n        {flexcol} In ({flex_cntrs})",     flex_cntrs = collapse(flex, ","))
 4: eval(expr, envir, enclos)
 5: eval(lhs, parent, parent)
 6: glue::glue("SELECT ScenarioId, {flexcol} CountryId, FactorId, YearId, DataValue\n        FROM
Execution halted
ERROR: Job failed: exit status 1

This happens from time to time, usually the CI job completes without errors on retry. Here is my devtools:session_info() output:

> devtools::session_info()
Session info -------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.2 (2016-10-31)
 system   x86_64, linux-gnu           
 ui       X11                         
 language (EN)                        
 collate  en_US.UTF-8                 
 tz       <NA>                        
 date     2017-04-25                  

Packages -----------------------------------------------------------------------
 package  * version    date       source                         
 devtools   1.12.0     2016-06-24 CRAN (R 3.3.0)                 
 digest     0.6.10     2016-08-02 cran (@0.6.10)                 
 glue     * 0.0.0.9000 2017-03-29 Github (tidyverse/glue@099b283)
 memoise    1.0.0      2016-01-29 CRAN (R 3.3.0)                 
 withr      1.0.2      2016-06-20 CRAN (R 3.3.0)        

Any ideas on how to debug further?

option for NA handling

.na = "NA" by default. If NULL, then 'NA's are propagated (as they currently are in devel).

Escape newlines

Would it make sense for

glue::glue("foo bar \
            baz")

to be equivalent to

glue::glue("foo bar baz")

so long messages can be broken down in several lines in the code?

Let glue class inherit from 'character' class as well for S3 method dispatch

Thanks for this great package. glue made my life easier with template strings.

But, one thing I feel a bit frustrated is that some S3 generic methods cannot process the glue object because they don't know the fact glue is almost character.

generate_msg <- function(x) {
  l <- list(msg = glue::glue('Praise the {x}!'))
  jsonlite::toJSON(l)
}

generate_msg("V8")
#> Error: No method asJSON S3 class: glue

class(glue::glue('Praise the {x}!', x = 'V8'))
#> [1] "glue"

I know just using unclass() or as.character will save me, but is it possible to let glue class inherit from character class? Or, are there some reason that we have to restrict its class glue only?

generate_msg <- function(x) {
  msg <- `class<-`(glue::glue('Praise the {x}!'), c('glue', 'character'))
  l <- list(msg = msg)
  jsonlite::toJSON(l)
}

generate_msg("V8")
#> {"msg":["Praise the V8!"]} 

Add $ Shorthand

f$"my name is {name}"

could work. Just class f and add a $ method like gsubfn does. Could also provide a different fun to avoid issues (e.g. F).

Saves a keystroke and also looks a tiny bit more like the python syntax.

This one is obviously low priority, but kind of cute, and different to the one I tweeted about.

Installation fails on Windows 10, R version 3.3.3

Perhaps an installation command is looking for a previous version of R?

> devtools::install_github('tidyverse/glue')
Downloading GitHub repo tidyverse/glue@master
from URL https://api.github.com/repos/tidyverse/glue/zipball/master
Error: running command '"C:/PROGRA~1/R/R-33~1.3/bin/x64/R" --no-site-file --no-environ --no-save --no-restore --quiet CMD config CC' had status 127
> sessionInfo()
R version 3.3.3 (2017-03-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 14393)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

loaded via a namespace (and not attached):
[1] httr_1.2.1 R6_2.2.0 tools_3.3.3 withr_1.0.2
[5] curl_2.4 memoise_1.0.0 git2r_0.18.0 digest_0.6.12
[9] devtools_1.12.0

Trim logic not quite right

It should trim including the last line.

t <- glue:::trim
  t("
      Hello,
      World.
    ")
# should be the following (based on the indention of the last line)
# "  Hello,\n  World."
# Actually is
#> "Hello,\nWorld."

glue_sql treats NA_character_ differently than other NAs

It appears that NA_character_ values are (erroneously?) special when using the new .na=NULL option in v1.2.0.

## FYI: dbconn is a RPostgres DBI connection
> dbconn <- DBI::dbConnect(RPostgres::Postgres(), host = myhost, dbname = mydb, user = me)

## a bunch of NAs of different type:
> l <- list(
    lgl = NA
   ,chr = NA_character_
   ,dbl = NA_real_
   ,int = NA_integer_
)

## first without the default .na = "NA" option:
> map_chr(l, function(x) glue_sql("foo = {x}", .con = dbconn))

          lgl          chr          dbl          int
   "foo = NA" "foo = 'NA'"   "foo = NA"   "foo = NA"

## now with .na = NULL, which should return _just_ <NA> for all four inputs:
> map_chr(l, function(x) glue_sql("foo = {x}", .con = dbconn, .na = NULL))

          lgl          chr          dbl          int
           NA "foo = 'NA'"           NA           NA

This appears to be specific to glue_sql, glue itself works as expected for all NA types.
Is this related to glue_sql or perhaps the underlying DBI calls? (FWIW I've tried with both RPostgres and RPostgreSQL and found identical results.)

glue isn't fast

bar <- 'baz'
microbenchmark(glue::glue('foo{bar}'))
# Unit: microseconds
#                   expr     min      lq     mean median       uq     max neval
#  glue::glue("foo{bar}") 291.851 343.165 433.5618 401.78 555.0745 753.867   100
microbenchmark(paste0('foo', bar))
# Unit: microseconds
#              expr  min    lq    mean median     uq    max neval
# paste0("foo", bar) 2.45 2.523 3.05519 2.6085 2.8555 36.524   100
microbenchmark(sprintf('foo%s', bar))
# Unit: nanoseconds
#                   expr min    lq    mean median     uq   max neval
#  sprintf("foo%s", bar) 825 947.5 1273.85 1111.5 1184.5 19195   100

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.