Ruby - 打印变量名称,然后打印其值

Bud*_*Joe 25 ruby metaprogramming function

编写函数(或DSLish)的最佳方法是什么,这将允许我在Ruby中编写此代码.我如何构造函数write_pair?

username = "tyndall"
write_pair username
# where write_pair username outputs 
username: tyndall
Run Code Online (Sandbox Code Playgroud)

有可能吗?寻找最简单的方法来做到这一点.

cly*_*yfe 21

当然有可能!

我的解决方案通过Object#object_id身份测试var:http://codepad.org/V7TXRxmL
它在绑定传递方式中瘫痪......
虽然它仅适用于本地变量,但它可以很容易地被"通用"添加使用其他范围变量列表方法instance_variables

# 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
Run Code Online (Sandbox Code Playgroud)

  • 我会非常想要伤害任何在项目中实际使用此代码的人. (10认同)
  • 这纯粹是边界的实验。 (2认同)

Ark*_*kku 15

如果您可以使用符号而不是变量名称,则可以执行以下操作:

def wp (s, &b)
  puts "#{s} = #{eval(s.to_s, b.binding)}"
end
Run Code Online (Sandbox Code Playgroud)

正在使用:

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
Run Code Online (Sandbox Code Playgroud)

请注意,必须将空块传递{}给方法,否则无法获取绑定以评估符号.


Dav*_*vid 5

在 Ruby 中实际上无法获取变量的名称。但你可以这样做:

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

甚至,

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


Ben*_*kes 5

我为此做了一个vim宏:

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

将您要检查的变量单独放在一行上,然后,i在普通模式下键入(逗号然后是i)。变成这样:

foo
Run Code Online (Sandbox Code Playgroud)

到这个:

puts "foo: #{(foo).inspect}"
Run Code Online (Sandbox Code Playgroud)

很好,因为它没有任何外部依赖项(例如,您不必加载使用它的库)。