Brainf**k to Ruby interpreter -- v3 Previous iteration.

I think this is about as good as it's gonna get, but just for kicks, let's do one more round of iterations.

As before, it's a very simple substitution from Brainfuck to Ruby, with fancy things like joining duplicate lines into one and indentation.

Some things that bug me:


The regex (/\++|-+|&lt;+|&gt;+|[.,\[\]]/) feels like it can be simplified, but I can't figure out how.
I feel like the map can be simplified, but I can't figure out how.
The constant repetition of #{'  ' * indent_level} bugs me, but I can't see how to get rid of it.
indent_level being declared outside of the scope of each feels like an anti-pattern, but AFAICT there's no better way to do it.




input_file, output_file = ARGV
code = IO.read(input_file).delete('^+-&lt;&gt;.,[]')

open(output_file, File::CREAT | File::WRONLY) do |output|
  output.puts &lt;&lt;-END.gsub(/^[ \t]*\||\s*#@.*$/, '')
    |#!/usr/bin/env ruby
    |class Mem &lt; Hash #@ Hash because it's more memory-efficient and allows negative values.
    |  def initialize; super(0); end
    |  def []=(i, val); super(i, val &amp; 255); end
    |end
    |data = Mem.new
    |pointer = 0
  END
  indent_level = 0
  code.scan(/\++|-+|&lt;+|&gt;+|[.,\[\]]/)
      .map do |string|
        case string[0]
          when '+' #String of "+"
            next "#{'  ' * indent_level}data[pointer] += #{string.length}"
          when '-' #String of "-"
            next "#{'  ' * indent_level}data[pointer] -= #{string.length}"
          when '&lt;' #String of "&lt;"
            next "#{'  ' * indent_level}pointer -= #{string.length}"
          when '&gt;' #String of "&gt;"
            next "#{'  ' * indent_level}pointer += #{string.length}"
          when '[' #Single "["
            ret = "#{'  ' * indent_level}until data[pointer] == 0"
            indent_level += 1
            next ret #Split it so that it's clear that indent is increased *after* the line
          when ']' #Single "]"
            indent_level -= 1
            next "#{'  ' * indent_level}end"
          when ',' #Single ","
            next "#{'  ' * indent_level}data[pointer] = $stdin.readbyte"
          when '.' #Single "."
            next "#{'  ' * indent_level}putc data[pointer]"
        end
      end.each { |line| output.puts(line) }
end
I'm not 100% sure this works in Ruby, but can you use constants with string interpolation? This string is repeated a lot. I doubt it will ever change, but if it does, it would be nice to only have to change it once. 


"#{'  ' * indent_level}data[pointer]"



Could be #{'  ' * indent_level}#{DATA}.