2

I want to write a simple debug method in Ruby for my Rails app:

foo = "bar"
debug(foo)

The debug method would return the string "foo: bar".

How do you get the name of the object (foo, in this case) in Ruby?

Working in Ruby 1.92.

Thanks.

B Seven
  • 44,484
  • 66
  • 240
  • 385
  • 3
    Why not just write: debug("foo") instead of debug(foo) ? – Candide Sep 15 '11 at 02:08
  • 4
    There's an important distinction here that may seem trivial at first: "foo" is not the name of the object. "foo" is the name of a variable. More than one variable may point to the same object. That's why this is not as straightforward as you might think. – daxelrod Sep 15 '11 at 02:22
  • 1
    Sorry, this is just a a terrible idea, and quite pointless. Use words to log debug messages, not variable names. – Candide Sep 15 '11 at 02:35
  • 2
    Related questions: http://stackoverflow.com/questions/58482/ruby-get-a-variables-name and http://stackoverflow.com/questions/3249786/get-the-name-of-a-local-variable – Andrew Grimm Sep 15 '11 at 04:12
  • 1
    i don't think its a terrible idea at all, if I know something is breaking in a method but really don't see where it is, I will just start puts spamming everything to try to find values that don't make sense. the sort of thing asked in the question makes that way simpler – Matt Briggs Sep 15 '11 at 04:13
  • It may not be a best practice, but I always write debug statements like `puts "var_name: " + var_name.to_s`. It doesn't have to stay in the codebase forever...just to see what's going on during testing. – B Seven Sep 15 '11 at 09:45

5 Answers5

3

check out log_buddy

from the readme:

a = "foo"
@a = "my var"
@@bar = "class var!"
def bark
 "woof!"
end

d { a }      # logs "a = 'foo'"
d { @a }     # logs "@a = 'my var'"
d { @@bar }  # logs "@@bar = 'class var!'"
d { bark }   # logs "bark = woof!"
Matt Briggs
  • 41,224
  • 16
  • 95
  • 126
2
def debug(var,val)
  puts "#{var}: #{val}"
end

debug("foo",foo)
glenn mcdonald
  • 15,290
  • 3
  • 35
  • 40
  • 2
    For this to work correctly, `debug`'s caller would have to call [binding](http://ruby-doc.org/core/classes/Kernel.html#M001448) and pass that to `debug`, so that `debug` could pass it to `eval`. Otherwise, the `eval` may be in the wrong scope to see the value of `foo`. See the [Binding](http://ruby-doc.org/core/classes/Binding.html) class for more info. – daxelrod Sep 15 '11 at 02:42
  • Oh, right, now I remember having to do that, and what a pain it was. Fixed answer to do the more reliable way. – glenn mcdonald Sep 15 '11 at 03:20
  • Oh, and just to say, one of the virtues of this simple technique is that once you get into it you're really likely to find that you actually often want to output more information than just the name. Like `debug("foo before starting import",foo)` and `debug("foo after clearing cache",foo)`... – glenn mcdonald Sep 15 '11 at 13:44
1

For completeness, here's a way you should not do it. This is a horrible idea, and will break in all kinds of ways:

According to Chris Shea, Section 8.6 in The Ruby Programming Language by Flanagan and Matz has this snippet (comments added for clarity):

class Object 
  def get_name #do not use this brittle technique
    line_number   = caller[0].split(':')[1].to_i
    line_executed = File.readlines(__FILE__)[line_number-1] 
    line_executed.match(/(\S+)\.get_name/)[1] #BAD IDEA: parsing Ruby with regular expressions
  end 
end

It "works" by finding the line number at which get_name was called, reading that line from the currently running file, and attempting to use a regular expression to parse out the name of the variable. With apologies to Zalgo, do not try to parse Ruby with regular expressions!

Community
  • 1
  • 1
daxelrod
  • 2,499
  • 1
  • 22
  • 30
0

I'm not sure you could reliably do this, particularly across Ruby implementations. What's your main goal in doing this? To eliminate manual generation of semantic information?

As others have stated, just printing a variable name isn't necessarily helpful on its own: without context, it may not be any more helpful than dumping the variable.

Seems like a better idea would be to use the normal logging mechanisms, and provide contextually-meaningful information along with symbol values.

Or just use pry.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • The reason for the downvote? On their own, somewhat meaningless. Educate me. – Dave Newton Sep 15 '11 at 04:34
  • Yep, if you search for "pry rails console" you can use it as your console, too. It'll cause your browser request to time out unless you're quick, of course. Really handy, though. – Dave Newton Sep 15 '11 at 11:39
  • @DaveNewton: I downvoted because the question is a reasonable enough one, and there was already a "don't do it" answer. – Andrew Grimm Sep 19 '11 at 23:06
0

As usual with Ruby, there's a gem for that: http://thinkrelevance.com/blog/2009/09/23/quick-and-easy-logging-with-logbuddy.html

It will output to stdout.

Thanks to Andrew Grimm (above) and Leventix.

B Seven
  • 44,484
  • 66
  • 240
  • 385