Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all output lost when using if statement without else in glue #266

Closed
SokolovAnatoliy opened this issue Apr 12, 2022 · 6 comments
Closed

Comments

@SokolovAnatoliy
Copy link

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
Copy link
Author

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.

@zeehio
Copy link
Contributor

zeehio commented Apr 26, 2022

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 🤯 😃 . 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.

@SokolovAnatoliy
Copy link
Author

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?

@MichaelChirico
Copy link
Contributor

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

@hadley
Copy link
Member

hadley commented Jan 25, 2023

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 #246

@hadley
Copy link
Member

hadley commented Jan 25, 2023

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

@hadley hadley closed this as completed Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants