Ruby - type the name of the variable and then its value

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 build the write_pair function?

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

Can this be done? Look for the easiest way to do this.

+21
function ruby metaprogramming
Apr 08 '10 at 21:34
source share
8 answers

Of course it is possible!

My solution checks var on Object # object_id identity: http://codepad.org/V7TXRxmL
He is crippled in the style of a fastening transition ...
Although it only works for local vars, it can easily be made "universal" by adding the use of other methods with enumeration of variables, such as 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 
+21
Apr 08 2018-10-10T00:
source share

If you can use a character instead of a variable name, you can do something like this:

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

Using:

 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 an empty block {} method or not get a binding to evaluate the character.

+14
Apr 08 2018-10-10T00:
source share

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 want to check on the line, and then type ,i (comma and then i) in normal mode. It does this:

 foo 

in it:

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

This is good because it has no external dependencies (for example, you do not need to load the library to use it).

+3
Jun 28 '10 at 13:48
source share

You cannot get the variable name in Ruby. But you can 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}" } 
+2
Apr 08 2018-10-18T00:
source share

This is one simple solution:

  def bug string puts string + eval(string) end 

This is more readable:

  def bug string puts '#' * 100 puts string + ': ' + eval(string).inspect end 

Called this way:

 bug "variable" 

If you need to carry the actual variable with you, you need to enter it twice, but then you can make it inline. In this way:

 puts "variable: #{variable}" 
+2
Mar 08 '17 at 9:48 on
source share

Based on previous answers related to characters and bindings ... if you use a name character as a character (who doesn't like to cut out extra keystrokes ?!), try the following:

 def wp(var_name_as_sym) # gets caller binding, which contains caller execution environment parent_binding = RubyVM::DebugInspector.open{|i| i.frame_binding(2) } # now puts the symbol as string + the symbol executed as a variable in the caller binding puts %Q~#{var_name_as_sym.to_s} = #{eval("#{var_name_as_sym.to_s}.inspect", parent_binding)}~ end aa=1 bb='some bb string' os = OpenStruct.new(z:26, y:25) 

Console output:

 > wp :aa aa = 1 => nil > wp :bb bb = "some bb string" => nil > wp :os os = #<OpenStruct z=26, y=25> => nil 

Using ruby ​​2.2.2p95

( banister credit to get call context bindings )

+2
Oct 19 '17 at 14:15
source share
 def write_pair var, binding puts "#{ var } = #{ eval(var, binding)}" end username = "tyndall" write_pair "username", binding 

This seems odd because a binding is never defined, but it works. From Ruby: getting the variable name :

The binding () method gives a Binding object that remembers the context at the method call point. Then you pass the binding to eval () and it evaluates the variable in that context.

Be sure to pass a string, not a variable.

+1
Feb 04 '14 at 19:36
source share
 # make use of dynamic scoping via methods and instance vars @_binding = binding def eval_debug(expr, binding = @_binding) "#{expr} => #{eval(expr, binding)}" end # sample invocation: x = 10 puts eval_debug "x" puts eval_debug "x**x" 
+1
Mar 17 '15 at 11:34
source share



All Articles