Ruby: fusionar variables en una cadena

95

Estoy buscando una mejor manera de fusionar variables en una cadena, en Ruby.

Por ejemplo, si la cadena es algo como:

"El animal actiondel second_animal"

Y tengo variables para animal, actiony second_animal, ¿cuál es la forma preferida de poner esas variables en la cadena?

MiedoMediocridad
fuente

Respuestas:

240

La forma idiomática es escribir algo como esto:

"The #{animal} #{action} the #{second_animal}"

Tenga en cuenta las comillas dobles (") que rodean la cadena: este es el desencadenante para que Ruby use su sustitución de marcador de posición incorporada. No puede reemplazarlas con comillas simples (') o la cadena se mantendrá como está.

Mike Woodhouse
fuente
2
Lo siento, tal vez simplifiqué demasiado el problema. La cadena se extraerá de una base de datos y la variable dependerá de varios factores. Normalmente, usaría un reemplazo para 1 o dos variables, pero esto tiene el potencial de ser más. ¿Alguna idea?
FearMediocrity
La construcción # {} es probablemente la más rápida (aunque eso todavía me parece contradictorio). Además de la sugerencia de gix, también puede ensamblar cadenas con + o <<, pero puede haber algunas cadenas intermedias creadas, lo cual es costoso.
Mike Woodhouse
La mejor manera de interpolar variables
Dragutescu Alexandru
115

Puede usar un formato similar a sprintf para inyectar valores en la cadena. Para eso, la cadena debe incluir marcadores de posición. Coloque sus argumentos en una matriz y use una de estas formas: (Para obtener más información, consulte la documentación de Kernel :: sprintf ).

fmt = 'The %s %s the %s'
res = fmt % [animal, action, other_animal]  # using %-operator
res = sprintf(fmt, animal, action, other_animal)  # call Kernel.sprintf

Incluso puede especificar explícitamente el número de argumento y barajarlo:

'The %3$s %2$s the %1$s' % ['cat', 'eats', 'mouse']

O especifique el argumento usando claves hash:

'The %{animal} %{action} the %{second_animal}' %
  { :animal => 'cat', :action=> 'eats', :second_animal => 'mouse'}

Tenga en cuenta que debe proporcionar un valor para todos los argumentos al %operador. Por ejemplo, no puede evitar definir animal.

gix
fuente
18

Usaría el #{}constructor, como se indica en las otras respuestas. También quiero señalar que hay una verdadera sutileza aquí a tener en cuenta aquí:

2.0.0p247 :001 > first_name = 'jim'
 => "jim" 
2.0.0p247 :002 > second_name = 'bob'
 => "bob" 
2.0.0p247 :003 > full_name = '#{first_name} #{second_name}'
 => "\#{first_name} \#{second_name}" # not what we expected, expected "jim bob"
2.0.0p247 :004 > full_name = "#{first_name} #{second_name}"
 => "jim bob" #correct, what we expected

Si bien las cadenas se pueden crear con comillas simples (como lo demuestran las variables first_namey last_name, el #{}constructor solo se puede usar en cadenas con comillas dobles.

Starkers
fuente
13
["The", animal, action, "the", second_animal].join(" ")

es otra forma de hacerlo.

Andrew Grimm
fuente
10

Esto se llama interpolación de cadenas, y lo haces así:

"The #{animal} #{action} the #{second_animal}"

Importante: solo funcionará cuando la cadena esté entre comillas dobles ("").

Ejemplo de código que no funcionará como esperabas:

'The #{animal} #{action} the #{second_animal}'
sqrcompass
fuente
Gracias por utilizar el término adecuado para que los nuevos programadores puedan aprender: interpolación.
Mike Bethany
3

El sistema de plantillas ERB estándar puede funcionar para su escenario.

def merge_into_string(animal, second_animal, action)
  template = 'The <%=animal%> <%=action%> the <%=second_animal%>'
  ERB.new(template).result(binding)
end

merge_into_string('tiger', 'deer', 'eats')
=> "The tiger eats the deer"

merge_into_string('bird', 'worm', 'finds')
=> "The bird finds the worm"
Clint Pachl
fuente
0

Puede usarlo con sus variables locales, así:

@animal = "Dog"
@action = "licks"
@second_animal = "Bird"

"The #{@animal} #{@action} the #{@second_animal}"

el resultado sería: "El perro lame al pájaro "

Níkolas La Porta
fuente