«Проблема» в том, что вы конвертируете массив в строку. В результате распаковки возвращается массив, и вы вызываете to_s, так что вы получите:
p "Michael".unpack("B*") # ["01001101011010010110001101101000011000010110010101101100"]
p "Michael".unpack("B*").to_s # "[\"01001101011010010110001101101000011000010110010101101100\"]"
Вы можете просто получить первый и единственный результат без необходимости применять to_s, и вы сможете выполнить необходимые замены:
"Michael".unpack("B*").first.gsub("1", "b").to_s.gsub("0", "a")
# "abaabbababbabaababbaaabbabbabaaaabbaaaababbaabababbabbaa"
Обратите внимание, что если вы просто заменяете 0 на a, а 1 на b, вы можете использовать tr
:
p "Michael".unpack("B*").first.tr("01", "ab")
# "abaabbababbabaababbaaabbabbabaaaabbaaaababbaabababbabbaa"
Тот же результат.