glue icon indicating copy to clipboard operation
glue copied to clipboard

all output lost when using if statement without else in glue

Open SokolovAnatoliy opened this issue 3 years ago • 3 comments

Hi, I was using an if statement in glue, and ran across something that I think this is not the intended behavior?

If I use an if statement without specifying the else (FALSE) condition, all output is lost. I am not sure if this is a bug, but it was not the behavior I was expecting. In the case that the else statement is not specified, it doesn't matter what is present in any other number of glue() statement, the combined glue string is empty.

I expected that the glue string when no else case was specified would return an empty string, and let me combine multiple if statements in sequence, without specifying the else.

Thanks!

## This fails
test1 = FALSE
stuff1 = glue("Hello")
thing1 = glue("{if(test1) \" you\" }")

stuff1+thing1 ## nothing is printed - any glue statements combined are lost

## This works
test2 = TRUE
stuff2 = glue("Hello")
thing2 = glue("{if(test2) \" you\" }") ## these work

stuff2+thing2

##This works when test is FALSE
test3 = FALSE
stuff3 = glue("Hello")
thing3 = glue("{if(test3) \" you\" else \" me\"}") ## this properly combines the statement

stuff3+thing3

## Combination of anything with the open ended if statement also results in a fail
stuff+thing1+thing3

SokolovAnatoliy avatar Apr 12 '22 17:04 SokolovAnatoliy

I guess also the same is observed from an empty glue statement, for example. stuff + glue(). I guess my expected behavior would be to return stuff, not nothing.

SokolovAnatoliy avatar Apr 12 '22 18:04 SokolovAnatoliy

One might say that, on your first example, if there is no "you", then there is no need to say "Hello" to anyone, and therefore the original example, labelled as "This fails" is actually consistent :exploding_head: :smiley: . I guess that's the reason why glue behaves the way it does.

I'm no glue expert, so I will try to understand a few things:

  • The code if(FALSE) "you" returns NULL.
  • glue({NULL}) by default returns a glue object of length zero.
  • glue({NULL}) + glue("potato") returns a glue object of length zero, but you would like it to return "potato".
  • glue("") + glue("potato") returns "potato", as we expected

So, a workaround that returns what you expect can be obtained using the .null argument:

  • glue({NULL}, .null = "") + glue("potato") returns "potato" as you'd like
## This works
test1 = FALSE
stuff1 = glue("Hello")
thing1 = glue('{if(test1) " you" }', .null = "")

stuff1+thing1 ## prints "Hello"

I hope this helps.

zeehio avatar Apr 26 '22 08:04 zeehio

Ok - that helps. I guess in your example, if you say "hello" in the woods and no one is around to hear it, you didnt actually say "hello"?

In the documentation for glue it states:

.null | [character(1): ‘character()’]Value to replace NULL values with. If character() whole output is character(). If NULL all NULL values are dropped (as in paste0()). Otherwise the value is replaced by the value of .null.

However, if you compare the output of paste0 and glue, the answer is not consistent.

paste0(NULL, "hello") [1] "hello" paste0(character(), "hello") [1] "hello"

glue::glue(NULL, "hello", .null = character()) ## this is the default

glue::glue(NULL, "hello", .null = NULL) hello

I guess the documentation says that the default is character(). So the addition of glue(character()) + glue("hello") is an empty glue string?

My question is: shouldn't this behave consistent with paste0?

SokolovAnatoliy avatar Apr 27 '22 14:04 SokolovAnatoliy

I believe I'm also getting bit by this, maybe the print() method for NULL needs to be updated? Might have made it easier to understand the issue:

x = 1
glue("{x} {x}")
# 1 1
glue("{x} {}") # nothing printed, not immediately clear why
glue("X} {}")
Error in eval(parse(text = text, keep.source = FALSE), envir) : 
  object 'X' not found

MichaelChirico avatar Oct 10 '22 07:10 MichaelChirico

Very minimal reprex:

glue::as_glue(character())

Created on 2023-01-25 with reprex v2.0.2

(And switching to stringr::str_view() won't help)

In terms of consistency, I think the main problems are described in https://github.com/tidyverse/glue/issues/246

hadley avatar Jan 25 '23 23:01 hadley

And printing is now in #290, so I'm going to close this issue.

hadley avatar Jan 25 '23 23:01 hadley