Listing functions that return strings

Can someone explain why the following snippet behaves?

l <- list()
AddFn <- function(str) { l[[length(l) + 1]] <<- function() { return(str) }}
AddFn("hello")
AddFn("there")
l[[1]]()  # Returns "hello" as expected
l[[2]]()  # Returns "there" as expected
for (letter in letters) AddFn(letter)
l[[3]]()  # Returns "z"

I expected to l[[3]]()return "a". What am I missing? What exactly does my AddFn function do?

Thanks in advance,

Adrian

+3
source share
2 answers

Lazy pricing often leads to the last pricing in the loop return. Try instead:

AddFn <- function(str) { force(str); l[[length(l) + 1]] <<- function() { return(str) }}
+7
source

This is nasty. The argument is strset to a promise that returns letter, but it is not actually evaluated until called through l[[3]](). Therefore, the value at this point is used!

If you change the last part to:

for (letter in letters) AddFn(letter)
letter="foo" 
l[[3]]()  # Returns "foo"

... you will see it more clearly. ... So, do what @DWin offers, and call first force.

+7
source

All Articles