Mapa una matriz modificando solo elementos que coinciden con una determinada condición

En Ruby, ¿cuál es la forma más expresiva de mapear una matriz de tal manera que ciertos elementos se modifiquen y los demás quedaron intactos?

Esta es una forma directa de hacerlo:

old_a = ["a", "b", "c"]                         # ["a", "b", "c"]
new_a = old_a.map { |x| (x=="b" ? x+"!" : x) }  # ["a", "b!", "c"]

Omitiendo el caso de "dejar en paz", por supuesto, si no es suficiente:

new_a = old_a.map { |x| x+"!" if x=="b" }       # [nil, "b!", nil]

Lo que me gustaría es algo como esto:

new_a = old_a.map_modifying_only_elements_where (Proc.new {|x| x == "b"}) 
        do |y|
          y + "!"
        end
# ["a", "b!", "c"]

¿Hay alguna forma agradable de hacer esto en Ruby (o tal vez Rails tiene algún tipo de método de conveniencia que aún no he encontrado)?

Gracias a todos por responder. Mientras colectivamente me convenciste de que es mejor usarmap con el operador ternario, ¡algunos de ustedes publicaron respuestas muy interesantes!

Respuestas a la pregunta(8)

Su respuesta a la pregunta