【问题标题】:How to get the name of an object in Ruby?如何在 Ruby 中获取对象的名称?
【发布时间】:2011-09-15 02:05:59
【问题描述】:

我想在 Ruby 中为我的 Rails 应用程序编写一个简单的调试方法:

foo = "bar"
debug(foo)

调试方法将返回字符串"foo: bar"

如何在 Ruby 中获取对象的名称(在本例中为 foo)?

在 Ruby 1.92 中工作。

谢谢。

【问题讨论】:

  • 为什么不直接写:debug("foo") 而不是 debug(foo) ?
  • 这里有一个重要的区别,乍一看似乎微不足道:“foo”不是对象的名称。 “foo”是变量的名称。多个变量可能指向同一个对象。这就是为什么这并不像您想象的那么简单。
  • 对不起,这只是一个糟糕的想法,而且毫无意义。使用单词来记录调试消息,而不是变量名。
  • 我根本不认为这是一个糟糕的主意,如果我知道某个方法出现了问题但真的不知道它在哪里,我会开始发送垃圾邮件以尝试查找没有意义的价值观。问题中提出的问题使这种方式更简单

标签: ruby-on-rails ruby object self


【解决方案1】:

查看log_buddy

来自自述文件:

a = "foo"
@a = "my var"
@@bar = "class var!"
def bark
 "woof!"
end

d { a }      # logs "a = 'foo'"
d { @a }     # logs "@a = 'my var'"
d { @@bar }  # logs "@@bar = 'class var!'"
d { bark }   # logs "bark = woof!"

【讨论】:

    【解决方案2】:
    def debug(var,val)
      puts "#{var}: #{val}"
    end
    
    debug("foo",foo)
    

    【讨论】:

    • 为了使其正常工作,debug 的调用者必须调用binding 并将其传递给debug,以便debug 可以将其传递给eval。否则,eval 可能会在错误的范围内查看foo 的值。有关详细信息,请参阅 Binding 课程。
    • 哦,对了,现在我记得必须这样做,那是多么痛苦。固定答案以做更可靠的方式。
    • 哦,顺便说一句,这种简单技术的优点之一是,一旦您开始使用它,您很可能会发现您实际上经常想要输出更多信息而不仅仅是名称.喜欢debug("foo before starting import",foo)debug("foo after clearing cache",foo)...
    【解决方案3】:

    为了完整起见,您应该不要这样做。这是一个可怕的想法,并且会以各种方式破坏:

    根据Chris Shea,Flanagan 和 Matz 的 Ruby 编程语言 中的第 8.6 节有这个 sn-p(为清楚起见添加了 cmets):

    class Object 
      def get_name #do not use this brittle technique
        line_number   = caller[0].split(':')[1].to_i
        line_executed = File.readlines(__FILE__)[line_number-1] 
        line_executed.match(/(\S+)\.get_name/)[1] #BAD IDEA: parsing Ruby with regular expressions
      end 
    end
    

    它通过查找调用 get_name 的行号,从当前运行的文件中读取该行,并尝试使用正则表达式解析出多变的。向Zalgo 道歉,不要尝试使用正则表达式解析 Ruby!

    【讨论】:

      【解决方案4】:

      我不确定您能否可靠地做到这一点,尤其是跨 Ruby 实现。你这样做的主要目标是什么?消除人工生成语义信息?

      正如其他人所说,仅打印变量名本身并不一定有帮助:没有上下文,它可能不会比转储变量更有帮助。

      似乎更好的主意是使用正常的日志记录机制,并提供具有上下文意义的信息以及符号值。

      或者只使用pry

      【讨论】:

      • 投反对票的原因是什么?对自己来说,有些无意义。教育我。
      • 是的,如果您搜索“pry rails console”,您也可以将其用作您的控制台。当然,除非你很快,否则它会导致你的浏览器请求超时。不过真的很方便。
      • @DaveNewton:我投了反对票,因为这个问题足够合理,而且已经有一个“不要这样做”的答案。
      【解决方案5】:

      像往常一样使用 Ruby,有一个宝石: http://thinkrelevance.com/blog/2009/09/23/quick-and-easy-logging-with-logbuddy.html

      它将输出到标准输出。

      感谢 Andrew Grimm(上图)和 Leventix。

      【讨论】:

      • (考虑到它的机制和限制,我很好奇它在不同实现中的效果如何。)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2016-09-03
      • 2011-02-23
      • 2017-12-16
      相关资源
      最近更新 更多