Skip to content

I think v needs to be in a closure here #48

@bennidhamma

Description

@bennidhamma

I've made a few hacks on this code to support loading project.json from an input parameter. (it's super crude - I have never worked with Go before, but if you like you can see my hatchet job here: https://github.com/themaven-net/boilr).

In the process, I saw a strange bug where things would work normally if I went through the prompts, but if I used defaults, then all the replacements were ending up being the same value. This has the smell of a closure-related bug all over it, and I seemed to find a spot where we are failing to enclose some key variables:

if t.ShouldUseDefaults {
   t.FuncMap[s] = func() interface{} {
	switch v := v.(type) {
	// First is the default value if it's a slice
	case []interface{}:
		return v[0]
	}
	return v
    }
} else {
        t.FuncMap[s] = prompt.New(s, v)
}

Notice how we put s and v into a closure when we invoke prompt.New, but we don't do it for the shouldUseDefaults case.

I ended up "fixing it" by putting the funcMap[s] assignment into a closure:

if t.ShouldUseDefaults {
      t.FuncMap[s] = func(s2 string, v2 interface{}) func() interface{} {
	return func() interface{} {
	  switch v2 := v2.(type) {
	  // First is the default value if it's a slice
	  case []interface{}:
	    tlog.Error(fmt.Sprintf("s: %v, v[0]: %s\n", s2, v2[0]))
	    return v2[0]
	  }
	  tlog.Error(fmt.Sprintf("s: %v, %v \n", s2, v2))
	  return v2
	}
      }(s, v)
    } else {
      t.FuncMap[s] = prompt.New(s, v)
    }

And now it works correctly for me. This is essentially what the prompt (non-default) mode is doing. It makes sense to me that we would need to retain s and v inside of a closure for the defaults like we do for the prompt path. I don't understand why the change I introduced would have caused this, but I can't imagine I'm the first person to see this behavior if it is indeed a bug.

Any idea what I'm not seeing? I can live with this, but it's definitely puzzling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions