String concatenation and interpolation in Ruby

I am just starting to learn Ruby (first programming) and have a basic syntax question regarding variables and various ways of writing code.

Chris Pine "Learn to Program" taught me how to write a basic program like this ...

num_cars_again= 2 puts 'I own ' + num_cars_again.to_s + ' cars.' 

This is great, but then I came across a tutorial on ruby.learncodethehardway.com and learned to write the exact same program like this ...

 num_cars= 2 puts "I own #{num_cars} cars." 

Both of them output the same thing, but obviously option 2 is a much shorter way to do this.

Is there any special reason why I should use one format over another?

+64
ruby string-concatenation string-interpolation
Apr 09 2018-12-12T00:
source share
5 answers

Whenever TIMTOWTDI (there is more than one way to do this), you should look for the pros and cons. Using string interpolation (second) instead of string concatenation (first):

Pros:

  • Not printed
  • Automatically calls to_s for you
  • More idiomatic in the Ruby community.
  • Faster at runtime

Minuses:

  • Automatically calls to_s for you (perhaps you thought you had a string, and the to_s not what you wanted, and hides the fact that it is not a string)
  • It is required to use " to delimit your string instead of ' (you may have the habit of using ' , or you previously typed a string using this, and only later you need to use string interpolation)
+62
Apr 09 2018-12-12T00:
source share

Both interpolation and concatenation have their strengths and weaknesses. Below I gave a benchmark that clearly shows where to use concatenation and where to use interpolation.

 require 'benchmark' iterations = 1_00_000 firstname = 'soundarapandian' middlename = 'rathinasamy' lastname = 'arumugam' puts 'With dynamic new strings' puts '====================================================' 5.times do Benchmark.bm(10) do |benchmark| benchmark.report('concatination') do iterations.times do 'Mr. ' + firstname + middlename + lastname + ' aka soundar' end end benchmark.report('interpolaton') do iterations.times do "Mr. #{firstname} #{middlename} #{lastname} aka soundar" end end end puts '--------------------------------------------------' end puts 'With predefined strings' puts '====================================================' 5.times do Benchmark.bm(10) do |benchmark| benchmark.report('concatination') do iterations.times do firstname + middlename + lastname end end benchmark.report('interpolaton') do iterations.times do "#{firstname} #{middlename} #{lastname}" end end end puts '--------------------------------------------------' end 

And below is the test result

 Without predefined strings ==================================================== user system total real concatination 0.170000 0.000000 0.170000 ( 0.165821) interpolaton 0.130000 0.010000 0.140000 ( 0.133665) -------------------------------------------------- user system total real concatination 0.180000 0.000000 0.180000 ( 0.180410) interpolaton 0.120000 0.000000 0.120000 ( 0.125051) -------------------------------------------------- user system total real concatination 0.140000 0.000000 0.140000 ( 0.134256) interpolaton 0.110000 0.000000 0.110000 ( 0.111427) -------------------------------------------------- user system total real concatination 0.130000 0.000000 0.130000 ( 0.132047) interpolaton 0.120000 0.000000 0.120000 ( 0.120443) -------------------------------------------------- user system total real concatination 0.170000 0.000000 0.170000 ( 0.170394) interpolaton 0.150000 0.000000 0.150000 ( 0.149601) -------------------------------------------------- With predefined strings ==================================================== user system total real concatination 0.070000 0.000000 0.070000 ( 0.067735) interpolaton 0.100000 0.000000 0.100000 ( 0.099335) -------------------------------------------------- user system total real concatination 0.060000 0.000000 0.060000 ( 0.061955) interpolaton 0.130000 0.000000 0.130000 ( 0.127011) -------------------------------------------------- user system total real concatination 0.090000 0.000000 0.090000 ( 0.092136) interpolaton 0.110000 0.000000 0.110000 ( 0.110224) -------------------------------------------------- user system total real concatination 0.080000 0.000000 0.080000 ( 0.077587) interpolaton 0.110000 0.000000 0.110000 ( 0.112975) -------------------------------------------------- user system total real concatination 0.090000 0.000000 0.090000 ( 0.088154) interpolaton 0.140000 0.000000 0.140000 ( 0.135349) -------------------------------------------------- 

Conclusion

If the strings are already defined and are sure that they will never be used, use concatination else using interpolation. Use a suitable one that will lead to better performance than one that is easy to retreat.

+7
Apr 11 '14 at 11:32
source share

@ user1181898 - IMHO, this is because it is easier to see what is happening. Point @Phrogz, interpolation string automatically calls to_s for you. As a newbie, you need to see what happens “under the hood” so that you learn the concepts and not just learn rote.

Think of it as a study of mathematics. You are learning the “long” way to understand concepts so you can use shortcuts when you really know what you are doing. I speak from experience b / c. I have not yet advanced in Ruby, but I have made enough mistakes to advise people not to. Hope this helps.

+3
Apr 09 2018-12-12T00:
source share

If you use a string as a buffer, I find that using concatenation ( String#concat ) is faster.

 require 'benchmark/ips' puts "Ruby #{RUBY_VERSION} at #{Time.now}" puts firstname = 'soundarapandian' middlename = 'rathinasamy' lastname = 'arumugam' Benchmark.ips do |x| x.report("String\#<<") do |i| buffer = String.new while (i -= 1) > 0 buffer << 'Mr. ' << firstname << middlename << lastname << ' aka soundar' end end x.report("String interpolate") do |i| buffer = String.new while (i -= 1) > 0 buffer << "Mr. #{firstname} #{middlename} #{lastname} aka soundar" end end x.compare! end 

Results:

 Ruby 2.3.1 at 2016-11-15 15:03:57 +1300 Warming up -------------------------------------- String#<< 230.615ki/100ms String interpolate 234.274ki/100ms Calculating ------------------------------------- String#<< 2.345M (± 7.2%) i/s - 11.761M in 5.041164s String interpolate 1.242M (± 5.4%) i/s - 6.325M in 5.108324s Comparison: String#<<: 2344530.4 i/s String interpolate: 1241784.9 i/s - 1.89x slower 

I guess I would say that interpolation generates a temporary string, so it’s slower.

+1
Nov 15 '16 at 2:08
source share

For recording only, you can use both double and single quotation marks with interpolation. Both are regular code. So:

 num_cars= 2 puts "I own #{num_cars} cars." puts 'I own #{num_cars} cars.' 
-2
Nov 28 '16 at 11:49
source share



All Articles