Estou procurando uma maneira mais elegante de concatenar seqüências de caracteres em Ruby.
Eu tenho a seguinte linha:
source = "#{ROOT_DIR}/" << project << "/App.config"
Existe uma maneira melhor de fazer isso?
E, nesse caso, qual é a diferença entre <<
e +
?
ruby
string-concatenation
dagda1
fonte
fonte
Respostas:
Você pode fazer isso de várias maneiras:
<<
mas essa não é a maneira usualCom interpolação de cordas
com
+
O segundo método parece ser mais eficiente em termos de memória / velocidade do que vi (embora não seja medido). Todos os três métodos lançarão um erro constante não inicializado quando ROOT_DIR for nulo.
Ao lidar com nomes de caminho, convém usar
File.join
para evitar bagunçar o separador de nomes de caminho.No final, é uma questão de gosto.
fonte
O
+
operador é a opção de concatenação normal e provavelmente é a maneira mais rápida de concatenar seqüências de caracteres.A diferença entre
+
e<<
é que<<
altera o objeto no lado esquerdo e+
não.fonte
+
e<<
serão praticamente os mesmos. Se você está lidando com muitas seqüências de caracteres, ou realmente muito grandes, pode notar uma diferença. Fiquei surpreso com o desempenho parecido deles. gist.github.com/28953115.times do ... end
bloco, por exemplo) para cada intérprete, você terá resultados mais precisos. Meus testes mostraram que a interpolação é o método mais rápido em todos os intérpretes Ruby. Eu esperava<<
ser o mais rápido, mas é por isso que fazemos benchmark.Se você está apenas concatenando caminhos, pode usar o próprio método File.join do Ruby.
fonte
de http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/
Usar o
<<
akaconcat
é muito mais eficiente do que+=
, pois o último cria um objeto temporal e substitui o primeiro pelo novo.resultado:
fonte
Como esse é um caminho, eu provavelmente usaria o array e ingressaria em:
fonte
Aqui está outra referência inspirada por essa essência . Ele compara concatenação (
+
), anexo (<<
) e interpolação (#{}
) para seqüências de caracteres dinâmicas e predefinidas.resultado:
Conclusão: a interpolação na RM é pesada.
fonte
Eu preferiria usar o nome do caminho:
sobre
<<
e+
de ruby docs:+
: Retorna uma nova String contendo other_str concatenada para str<<
: Concatena o objeto especificado para str. Se o objeto for um Fixnum entre 0 e 255, ele será convertido em um caractere antes da concatenação.então a diferença está no que se torna no primeiro operando (
<<
faz alterações no lugar,+
retorna uma nova string para que a memória fique mais pesada) e qual será o primeiro operando é Fixnum (<<
será adicionado como se fosse um caractere com código igual a esse número,+
aumentará erro)fonte
Pathname('/home/foo') + '/etc/passwd' # => #<Pathname:/etc/passwd>
. Isso ocorre por design, com base no exemplo do rubydoc. Parece que File.join é mais seguro.(Pathname(ROOT_DIR) + project + 'App.config').to_s
se você deseja retornar um objeto string.Deixe-me mostrar a você toda a minha experiência com isso.
Eu tive uma consulta que retornou 32k de registros, para cada registro eu chamei um método para formatar esse registro de banco de dados em uma string formatada e concatená-la em uma String que ao final de todo esse processo se transformará em um arquivo em disco.
Meu problema era que, segundo os registros, em torno de 24k, o processo de concatenação da String causava dor.
Eu estava fazendo isso usando o operador '+' regular.
Quando mudei para o '<<' era como mágica. Foi muito rápido.
Então, lembrei-me dos meus velhos tempos - tipo 1998 - quando eu estava usando Java e concatenando String usando '+' e mudei de String para StringBuffer (e agora nós, desenvolvedor Java, temos o StringBuilder).
Eu acredito que o processo de + / << no mundo Ruby é o mesmo que + / StringBuilder.append no mundo Java.
O primeiro realoca o objeto inteiro na memória e o outro apenas aponta para um novo endereço.
fonte
Concatenação você diz? Como sobre o
#concat
método então?Com toda a justiça,
concat
é alias como<<
.fonte
"foo" "bar" 'baz" #=> "foobarabaz"
Aqui estão mais maneiras de fazer isso:
E assim por diante ...
fonte
Você também pode usar da
%
seguinte maneira:Essa abordagem também funciona com
'
aspas (simples).fonte
Você pode usar
+
ou<<
operador, mas na.concat
função ruby é o mais preferível, pois é muito mais rápido que outros operadores. Você pode usá-lo como.fonte
.
após o seu últimoconcat
não?A situação importa, por exemplo:
No primeiro exemplo, concatenar com o
+
operador não atualizará ooutput
objeto, no entanto, no segundo exemplo, o<<
operador atualizará ooutput
objeto a cada iteração. Então, para o tipo de situação acima,<<
é melhor.fonte
Você pode concatenar diretamente na definição de sequência:
fonte
Para o seu caso em particular, você também pode usar
Array#join
ao construir o tipo de string do caminho do arquivo:Isso tem um efeito colateral agradável de converter automaticamente tipos diferentes em string:
fonte
Para fantoche:
fonte