代码之家  ›  专栏  ›  技术社区  ›  BuddyJoe

ruby-打印变量名及其值

  •  23
  • BuddyJoe  · 技术社区  · 14 年前

    写一个函数(或者DSLish函数)的最佳方法是什么,它允许我用Ruby编写这段代码。如何构造函数write_对?

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

    有可能吗?寻找最简单的方法。

    8 回复  |  直到 7 年前
        1
  •  21
  •   damon Curtis Snowden    8 年前

    当然有可能!

    我的解决方案按对象测试var对象ID标识: 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
    
        2
  •  14
  •   Arkku    12 年前

    如果可以使用符号而不是变量名,可以这样做:

    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
    

    请注意,必须通过空块 {} 或者它无法获取绑定来计算符号。

        3
  •  4
  •   Benjamin Oakes    14 年前

    我做了一个 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}"
    

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

        4
  •  4
  •   memius    7 年前

    这是一个简单的解决方案:

      def bug string
        puts string + eval(string)
      end
    

    这是更易读的:

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

    因此调用它:

    bug "variable"
    

    如果需要携带实际变量,则必须键入两次,然后才能以内联方式进行。因此:

    puts "variable: #{variable}"
    
        5
  •  4
  •   DA2128    7 年前

    基于以前与符号和绑定相关的答案…如果将变量名作为符号传递给您(谁不喜欢删除多余的击键呢?!试试这个:

    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

    (信贷) banister 对于 getting binding 调用上下文)

        6
  •  3
  •   David    14 年前

    在Ruby中不能真正获得变量的名称。但是你可以这样做:

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

    甚至

    username = "tyndall"
    data = {"username", "password", "favorite_color"}
    data.each { |param|
       value = eval(param)
       puts "#{param}: #{value}"
    }
    
        7
  •  2
  •   Community Dunja Lalic    7 年前
    def write_pair var, binding
      puts "#{ var } = #{ eval(var, binding)}"
    end
    
    
    username = "tyndall"
    write_pair "username", binding
    

    这看起来很奇怪,因为绑定从未被定义过,但它是有效的。从 Ruby: getting variable name :

    binding()方法提供一个绑定对象,该对象记住 调用方法时的上下文。然后通过一个绑定 在eval()中,它计算该上下文中的变量。

    一定要传递一个字符串,而不是变量。

        8
  •  1
  •   balrog    9 年前
    # 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"