Ruby: Mesclando variáveis ​​em uma string

95

Estou procurando uma maneira melhor de mesclar variáveis ​​em uma string, em Ruby.

Por exemplo, se a string for algo como:

"O animal actiono second_animal"

E eu tenho variáveis ​​para animal, actione second_animalqual é a maneira preferida de colocar essas variáveis ​​na string?

Mediocridade do medo
fonte

Respostas:

240

A forma idiomática é escrever algo assim:

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

Observe as aspas duplas (") ao redor da string: este é o gatilho para Ruby usar sua substituição de placeholder embutida. Você não pode substituí-los por aspas simples (') ou a string será mantida como está.

Mike Woodhouse
fonte
2
Desculpe, talvez eu tenha simplificado demais o problema. A String será retirada de um banco de dados e a variável depende de uma série de fatores. Normalmente, eu usaria uma substituição para 1 ou duas variáveis, mas isso tem potencial para ser mais. Alguma ideia?
FearMediocrity de
A construção # {} é provavelmente a mais rápida (embora isso ainda pareça contra-intuitivo para mim). Além da sugestão do gix, você também pode montar strings com + ou <<, mas pode haver algumas strings intermediárias criadas, o que é caro.
Mike Woodhouse
Melhor maneira de interpolar variáveis
Dragutescu Alexandru
115

Você pode usar a formatação semelhante a sprintf para injetar valores na string. Para isso, a string deve incluir marcadores de posição. Coloque seus argumentos em uma matriz e use uma das seguintes maneiras: (Para obter mais informações, consulte a documentação 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

Você pode até especificar explicitamente o número do argumento e embaralhá-los:

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

Ou especifique o argumento usando chaves hash:

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

Observe que você deve fornecer um valor para todos os argumentos para o %operador. Por exemplo, você não pode evitar definir animal.

gix
fonte
18

Eu usaria o #{}construtor, conforme declarado pelas outras respostas. Também quero salientar que há aqui uma sutileza real a ser observada:

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

Embora as strings possam ser criadas com aspas simples (conforme demonstrado pelas variáveis first_namee last_name, o #{}construtor só pode ser usado em strings com aspas duplas.

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

é outra maneira de fazer isso.

Andrew Grimm
fonte
10

Isso é chamado de interpolação de string, e você faz assim:

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

Importante: só funcionará quando a string estiver entre aspas duplas ("").

Exemplo de código que não funcionará como você esperava:

'The #{animal} #{action} the #{second_animal}'
sqrcompass
fonte
Obrigado por usar o termo apropriado para que novos programadores possam aprender: interpolação.
Mike Bethany
3

O sistema de modelos ERB padrão pode funcionar para o seu cenário.

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
fonte
0

Você pode usá-lo com suas variáveis ​​locais, assim:

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

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

a saída seria: "O cachorro lambe o pássaro "

Níkolas La Porta
fonte