class Dotenv::Parser

It allows for variable substitutions, command substitutions, and exporting of variables.
Parses the ‘.env` file format into key/value pairs.

def call(...)

def call(...)
  new(...).call
end

def call

def call
  @string.scan(LINE) do
    match = $LAST_MATCH_INFO
    if existing?(match[:key])
      # Use value from already defined variable
      @hash[match[:key]] = ENV[match[:key]]
    elsif match[:export] && !match[:value]
      # Check for exported variable with no value
      if !@hash.member?(match[:key])
        raise FormatError, "Line #{match.to_s.inspect} has an unset variable"
      end
    else
      @hash[match[:key]] = parse_value(match[:value] || "")
    end
  end
  @hash
end

def existing?(key)

Determine if a variable is already defined and should not be overwritten.
def existing?(key)
  !@overwrite && key != "DOTENV_LINEBREAK_MODE" && ENV.key?(key)
end

def expand_newlines(value)

def expand_newlines(value)
  if (@hash["DOTENV_LINEBREAK_MODE"] || ENV["DOTENV_LINEBREAK_MODE"]) == "legacy"
    value.gsub('\n', "\n").gsub('\r', "\r")
  else
    value.gsub('\n', "\\\\\\n").gsub('\r', "\\\\\\r")
  end
end

def initialize(string, overwrite: false)

def initialize(string, overwrite: false)
  # Convert line breaks to same format
  @string = string.gsub(/\r\n?/, "\n")
  @hash = {}
  @overwrite = overwrite
end

def parse_value(value)

def parse_value(value)
  # Remove surrounding quotes
  value = value.strip.sub(QUOTED_STRING, '\2')
  maybe_quote = Regexp.last_match(1)
  # Expand new lines in double quoted values
  value = expand_newlines(value) if maybe_quote == '"'
  # Unescape characters and performs substitutions unless value is single quoted
  if maybe_quote != "'"
    value = unescape_characters(value)
    self.class.substitutions.each { |proc| value = proc.call(value, @hash) }
  end
  value
end

def unescape_characters(value)

def unescape_characters(value)
  value.gsub(/\\([^$])/, '\1')
end