代码之家  ›  专栏  ›  技术社区  ›  John Dibling

获取局部变量的名称

  •  8
  • John Dibling  · 技术社区  · 15 年前

    foo = 1
    bar = "42"
    baz = Hash.new
    
    [foo, bar, baz].each do |v|
        puts "#{v.???} = (#{v.class}) #{v}"
        end
    

    我希望这个程序的输出是这样的:

    foo = (Fixnum) 1 
    bar = (String) 42 
    baz = (Hash) ...
    

    我不知道是什么 ???

    4 回复  |  直到 15 年前
        1
  •  14
  •   Leventix    15 年前
    foo = 1
    bar = "42"
    baz = Hash.new
    
    %w(foo bar baz).each do |vn|
        v = eval(vn)
        puts "#{vn} = (#{v.class}) #{v}"
    end
    

    但是如果你想要一个只有一个参数的方法,这当然帮不了你。

        2
  •  4
  •   Wayne Conrad    9 年前

    他们的名字 .

    #!/usr/bin/ruby1.8
    
    def q(*stuff, &block)
      if block
        s = Array(block[]).collect do |expression|
          value = eval(expression.to_s, block.binding).inspect
          "#{expression} = #{value}"
        end.join(', ')
        $stderr.puts s
      else
        stuff.each do
          |thing| $stderr.print(thing.inspect + "\n")
        end
      end
    end
    
    i = 1
    q i       # => 1
    q {:i}    # => i = 1
    
    name = "Fred"
    q [name, name.length]         # => ["Fred", 4]
    q {[:name, 'name.length']}    # => name = "Fred", name.length = 4
    

    q 功能等,现在在 cute_print 宝石。

        3
  •  3
  •   Adrian    15 年前

    不,因为 foo bar / baz 不是代码中的实例变量。它们是局部变量(实例变量以 @ ). 有一种方法可以通过实例变量和 Object#instance_variables 方法,不过:

    @foo = 1
    @bar = 2
    @baz = 3
    
    instance_variables.each do |var|
      value = instance_variable_get var
      puts "#{var} = (#{value.class}) #{value}"
    end
    
    # outputs:
    # @foo = (Fixnum) 1
    # @bar = (Fixnum) 2
    # @baz = (Fixnum) 3
    

    要获取特定实例变量的名称,请遍历所有实例变量,直到找到一个值与实例变量匹配的实例变量。

        4
  •  2
  •   Jörg W Mittag    15 年前
    foo = 1
    bar = "42"
    baz = Hash.new
    
    Varspec = Struct.new(:name, :type, :value, :inspect_str) do
      def to_s
        "#{name} = (#{type}) #{inspect_str}"
      end
    end
    
    lvars = local_variables.map {|lvar|
      lvar = lvar.to_s
      val = eval(lvar)
      val = val.dup rescue val
      Varspec.new(lvar, val.class, val, val.inspect)
    }
    
    puts lvars
    # baz = (Hash) {}
    # bar = (String) "42"
    # foo = (Fixnum) 1
    

    推荐文章