Ruby - print the variable name and then its value

62,495

Solution 1

Sure it is possible!

My solution tests the var by Object#object_id identity: http://codepad.org/V7TXRxmL
It's crippled in the binding passing style ...
Although it works just for local vars yet, it can be easily be made "universal" adding use of the other scope-variable-listing methods like instance_variables etc.

# the function must be defined in such a place 
# ... so as to "catch" the binding of the vars ... cheesy
# otherwise we're kinda stuck with the extra param on the caller
@_binding = binding
def write_pair(p, b = @_binding)
  eval("
    local_variables.each do |v| 
      if eval(v.to_s + \".object_id\") == " + p.object_id.to_s + "
        puts v.to_s + ': ' + \"" + p.to_s + "\"
      end
    end
  " , b)
end

# if the binding is an issue just do here:
# write_pair = lambda { |p| write_pair(p, binding) }

# just some test vars to make sure it works
username1 = "tyndall"
username  = "tyndall"
username3 = "tyndall"

# the result:
write_pair(username)
# username: tyndall

Solution 2

If it's possible for you to use a symbol instead of the variable name, you could do something like this:

def wp (s, &b)
  puts "#{s} = #{eval(s.to_s, b.binding)}"
end

In use:

irb(main):001:0> def wp (s, &b)
irb(main):002:1>   puts "#{s} = #{eval(s.to_s, b.binding)}"
irb(main):003:1> end
=> nil
irb(main):004:0> var = 3
=> 3
irb(main):005:0> wp(:var) {}
var = 3

Note that you must pass the empty block {} to the method or it cannot get the binding to evaluate the symbol.

Solution 3

You can't actually get a variable's name in Ruby. But you could do something like this:

data = {"username" => "tyndall"}

Or even,

username = "tyndall"
data = {"username", "password", "favorite_color"}
data.each { |param|
   value = eval(param)
   puts "#{param}: #{value}"
}

Solution 4

I made a vim macro for this:

" Inspect the variable on the current line (in Ruby)
autocmd FileType ruby nmap ,i ^"oy$Iputs "<esc>A: #{(<esc>"opA).inspect}"<esc>

Put the variable you'd like to inspect on a line by itself, then type ,i (comma then i) in normal mode. It turns this:

foo

into this:

puts "foo: #{(foo).inspect}"

This is nice because it doesn't have any external dependencies (e.g. you don't have to have a library loaded up to use it).

Solution 5

This is a simple solution:

  def write_pair(variable)
    puts variable + eval(variable)
  end

This is more readable:

 def write_pair(variable)
    puts 'A' * 100
    puts variable + ': ' + eval(variable).inspect
    puts 'Z' * 100
 end

Invocation:

write_pair "variable"
Share:
62,495
BuddyJoe
Author by

BuddyJoe

I like to code C# and work with the web. Still learning.

Updated on April 23, 2020

Comments

  • BuddyJoe
    BuddyJoe about 4 years

    What is the best way to write a function (or something DSLish) that will allow me to write this code in Ruby. How would I construct the function write_pair?

    username = "tyndall"
    write_pair username
    # where write_pair username outputs 
    username: tyndall
    

    Is it possible to do? Looking for the most simple way to do this.