daniel-lucraftの回答をベースとして使用して (質問に回答したのは彼だけのようです)、この問題を堅牢な方法で解決することにしました。以下に、このソリューションのコードを示します。
# encoding: utf-8
class String
  INTERPOLATE_DELIMETER_LIST = [ '"', "'", "\x02", "\x03", "\x7F", '|', '+', '-' ]
  def interpolate(data = {})
    binding = Kernel.binding
    data.each do |k, v|
      binding.local_variable_set(k, v)
    end
    delemeter = nil
    INTERPOLATE_DELIMETER_LIST.each do |k|
      next if self.include? k
      delemeter = k
      break
    end
    raise ArgumentError, "String contains all the reserved characters" unless delemeter
    e = s = delemeter
    string = "%Q#{s}" + self + "#{e}"
    binding.eval string
  end
end
output =
begin
  File.read("data.txt").interpolate(foo: 3)
rescue NameError => error
  puts error
rescue ArgumentError => error
  puts error
end
p output
入力用
he #{foo} he
出力が得られます
 "he 3 he"
入力
"he #{bad} he\n"
NameError 例外が発生します。そして入力
"\"'\u0002\u0003\u007F|+-"
ArgumentError 例外が発生し、入力に使用可能なすべての区切り文字が含まれていることを訴えます。