Thursday, March 31, 2011

Easiest Way to Print Non-Strings in Ruby

I'm constantly doing this

puts “The temperature is “ + String(temperature) + “.”

in my debugging code, and another option is to use interpolation

puts “The temperature is #{temperature}.”

is there any less cumbersome way to do this?

Edit: This is just for debugging, if that matters.

From stackoverflow
  • None that are all that worthwhile for small cases like that.

    Though, you should prefer interpolation as it's less expensive than concatenation.

  • The best way to insert dynamic variables into strings is

    #interpolation
    "foo #{my_var} bar"
    

    It will call the to_s method on whatever object the expression returns and insert that string. It really the same as

    #concatenation
    "foo " + my_var.to_s + " bar"
    

    But, as wfarr metioned, its faster to do interpolation. Easier to read too.

    Thanatos : It appears you got it backwards. Interpolation is the first example. Concatenation is the second example you gave.
    Squeegy : Perhaps it got misinterpreted that way. I clarified with labels :)
    Yar : I had forgotten baout the .to_s method. Not a bad option... depends on your typing habits. I am not using this stuff in real code, but just to figure out what's happening.
    Squeegy : to_s is generally THE way to turn an object into a string. It's defined on the Object class that all ruby objects inherit from so its always available. If you write your own classes its encouraged to override it with a decent implementation.
  • There's always the possibility to use printf style formatting:

    "The temperature is %s" % temperature
    

    This would allow for finer formatting of numbers, etc. as well. But honestly, how much less "cumbersome" than using #{} interpolation can you expect to get?

    Yar : To be honest, I type on a Spanish keyboard but I switch to English format half the time, so finding the number key and brackets is just not as easy as "thinger" + thinger like in Java. But yeah, the interpolation syntax is workable.
  • Another way is to do something stupid like this:

    "The temperature is %s." % temperature.to_s

    Personally I'd use interpolation

  • A slightly different approach is to use assertions in automated tests.

    For example using Test::Unit :-

    assert_equal 25, temperature
    

    I find that using automated tests dramatically cuts down on the amount of debugging code I have to write.

    Yar : Very interesting, I'll check into this possibility. Answers like this make my stupid questions worth it.
    Yar : So how can I get this code running from a Ruby program? TestCase.assert_not_nil(blah) I know I need some requires or something.
    floehopper : require 'test/unit' class MyTest < Test::Unit::TestCase def test_should_be_hot_today ... assert_equal 25, temperature end end
    floehopper : Alternatively if you just want the assertions: require 'test/unit/assertions' include Test::Unit::Assertions ... assert_equal 25, temperature
    floehopper : See http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit/Assertions.html
  • Use Kernel#p

    p temperature #=> 10.25
    

    When I'm debugging, I often label such statements just by copying the line, and using inserting a colon, making the variable into a symbol.

    p :attributes #=> :attributes
    p attributes  #=> { :mood => "happy", 5 => [] }
    

    Or

    p [:location, location] #=> [ :location, "@ work" ]
    

    Note that Kernel#p calls #inspect on its arguments, instead of #to_s, but this normally provides more useful debugging info anyway.

    Yar : Wow. Nice stuff. I'll check it out. Anything that can save typing in my eventually-deleted-statements helps.

0 comments:

Post a Comment