Here is my solution, longer than most but pretty clean IMHO:

class Array
  # Just to be different I'm going to use Stephen
  # Waits' shuffle from ruby-talk archives (Dec 2005)
  # instead of the usual sort_by {rand}
  def shuffle
    h = Hash.new
    self.each { |v| h[rand(1000000000)] = v }
    h.keys.sort.collect { |k| h[k] }
  end
end

class String
  def munge
    # Only munge words longer than 3
    return self unless self.length > 3

    shuffled = middle = self[1..-2].scan(/./)
    # Ensure it is shuffled
    shuffled = shuffled.shuffle while (shuffled == middle)
    self[0..0] + shuffled.join + self[-1..-1]
  end
end

class Munger
  def self.munge(lines)
    lines.collect do |line|
      line.gsub(/[A-Za-z]*/) do |word|
        word.munge
      end
    end
  end
end

if $0 == __FILE__
  # Just read from STDIN
  puts Munger.munge(STDIN.readlines)
end