簡體   English   中英

Ruby - 打印變量名,然后是它的值

[英]Ruby - print the variable name and then its value

編寫允許我在 Ruby 中編寫此代碼的函數(或類似 DSL 的東西)的最佳方法是什么。 我將如何構造函數 write_pair?

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

有可能嗎? 尋找最簡單的方法來做到這一點。

當然有可能!

我的解決方案通過 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

如果您可以使用符號代替變量名稱,您可以執行以下操作:

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

正在使用:

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

請注意,您必須將空塊{}傳遞給方法,否則它無法獲得綁定來評估符號。

您實際上無法在 Ruby 中獲取變量的名稱。 但是你可以做這樣的事情:

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

甚至,

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

我為此做了一個vim宏:

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

將您要檢查的變量單獨放在一行上,然后在正常模式下鍵入,i (逗號然后 i)。 它變成了這樣:

foo

進入這個:

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

這很好,因為它沒有任何外部依賴項(例如,您不必加載庫即可使用它)。

這是一個簡單的解決方案:

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

這更具可讀性:

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

調用:

write_pair "variable"

基於先前與符號和綁定相關的答案......如果將變量名稱作為符號傳遞對你有用(誰不喜歡減少額外的擊鍵?!),試試這個:

def wp(var_name_as_sym)
  # gets caller binding, which contains caller's 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's 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)

控制台輸出:

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

使用 ruby​​ 2.2.2p95

歸功於欄桿獲得調用上下文的綁定

def write_pair var, binding
  puts "#{ var } = #{ eval(var, binding)}"
end


username = "tyndall"
write_pair "username", binding

這看起來很奇怪,因為從未定義綁定,但它有效。 Ruby:獲取變量名稱

binding() 方法提供了一個 Binding 對象,該對象會記住調用該方法時的上下文。 然后將綁定傳遞給 eval(),它會在該上下文中評估變量。

一定要傳遞一個字符串,而不是變量。

# 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"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM