Hacker News new | ask | show | jobs
by NateDad 4434 days ago
Uh, grabbing variables out of the current scope to format your string is most certainly magical. It's also way less explicit than actually passing variables into a formatting function.

It might be a little harder to read, but that's a lot different than explicit.

fmt.Sprintf("Hello %s!", username) is very explicitly using the username variable from the local scope, and nothing but the username variable can ever get included in the output string. At most, a user could put a %s in their string, and get the username to appear somewhere else in the output... but they wouldn't be revealing data that wasn't already intended to be printed out.

In comparison, interpolation is opening a door to let anyone extract whatever variables happen to be in scope at the time by putting #{password} or #{secret_key} in their string. By moving the definition of what variables get printed out into the data, you're opening a really big hole in your code... it also makes it a lot harder for the compiler to check for correctness.

1 comments

Can you give an example of your last point?

A language like Ruby will only perform interpolation on string literals, so there isn't a way (that I know of) for data to inject interpolated strings.

Interpolation isn't the same thing as eval.

I guess that's my lack of knowledge of how Ruby's string interpolation works. I assumed it worked like any old string format, which in other languages can use whatever string is passed into the formatting function. It sounds like that's not the case for Ruby's string interpolation. My apologies for jumping to conclusions. I guess it's my statically compiled mindset that assumes a string is a string.
You can kind of think of it as syntactic sugar over adding strings that desugars at the compilation stage.

"abc #{x} def" would desugar to "abc"+x+"def"

Because it's happening at the compilation stage, it can only be done on string literals (which as we've seen is actually an advantage security wise).

The reality is actually a tad more complicated, because you can make efficiency improvements and only create one string instead of all the intermediate strings etc. but the effect is the same.