【问题标题】:How do I find where a constant is defined in Ruby?如何找到在 Ruby 中定义常量的位置?
【发布时间】:2012-04-09 18:01:58
【问题描述】:

使用pry,通过edit-method 命令很容易找到定义方法的位置并查看源代码。然而,阶级本身并没有对应关系。当该类没有定义自己的方法时,很难通过pry 找到源。

类是常量,因此相当于询问在哪里可以找到定义特定 Ruby 常量的源。非常感谢。

【问题讨论】:

  • 您能接受之前问题的答案吗?
  • @Arsen7 哦,非常感谢你提醒我。我对这个社区很陌生。我现在已经接受了。
  • 很好。 :-) 那么grep 呢?或者,实际上,你的意思是 this 是我提醒你的? ;-)
  • @Arsen7 哈哈哈我完全没有发现任何自私:) 天哪,我开始爱上这个社区了。
  • 是的,grep 如果您至少知道可能的范围并且范围很小,那就可以了。有时主项目依赖于太多的依赖项,并且常量是在其他地方定义的。

标签: ruby constants


【解决方案1】:

在 ruby​​ 中,$"包含通过Kernel.load 加载的所有文件名。 所以你可以尝试这样的事情:

constant = User
$".detect{|load_path|
  load_path.include?(constant.to_s.underscore)
}

注意:underscore 方法是 Rails/ActiveSupport 的一部分

【讨论】:

  • 这是个好建议!
  • 很好的答案。我发现 underscore 在 Ruby 2.4.2 上的 String 中对我不可用。我用downcase 解决了问题,但是如果你的类名是多个单词,你需要以某种方式把它变成蛇形大小写。
【解决方案2】:

从 Ruby 2.7 开始,有一个更好的方法可以做到这一点,即Module.const_source_location

> Admin.const_source_location(:LIMIT)
#=> ["SOME_PATH/user.rb", 2]

参考资料:

【讨论】:

    【解决方案3】:

    使用ack,有时如果我达到 Pry(和 Ruby)的极限,我会使用它。它的好处是您可以使用它的 shell 集成功能从 Pry 本身内部调用它,通常只需键入 .ack ClassName 就可以了,但是它要求在当前目录下的文件中定义该类。

    如果当前目录中没有定义该类,那么您总是可以求助于查找其方法之一,从那里获取源位置,然后使用 Pry 的 cat 命令显示它(使用语法高亮)或 Pry 的 edit 命令直接跳转到其定义。

    一个类没有定义任何实例方法的情况相当罕见——而且这样的类通常也很无趣:)

    编辑

    最新版本的 Pry (0.9.9) 现在可以使用普通的show-source 命令显示模块/类的源代码。但是它要求模块/类至少有一个定义的方法

    【讨论】:

    • 考虑ripgrep 而不是ack,它更快! ag 也是一个不错的选择。
    【解决方案4】:

    如果您要查找的常量有方法(是类或模块),您可以使用 Method 类找出它的定义位置。

    class Foo
      def bar
      end
    
      def self.baz
      end
    end
    
    Foo.instance_method(:bar).source_location
    Foo.method(:baz).source_location
    

    有点小技巧,对纯常量 class Foo; BAHZ = 2; end 没有帮助,但总比没有好。

    【讨论】:

      【解决方案5】:

      一种用于调试目的的 hacky 方法:启动控制台(例如使用 binding.irb)并重新定义常量。您将收到一条错误消息,其中包含先前的定义路径!

      > Foo = ""
      (irb):11: warning: already initialized constant Foo
      /path/to/foo.rb:1: warning: previous definition of Foo was here
      => ""
      

      【讨论】:

      • 哇,没想到,这也适用于模块和类,太棒了!
      • 我也为 Class 和 Class 方法找到了这个 gem,也许它对某人也有帮助 github.com/daveallie/where_is
      • 这很棒,因为我正在处理的项目还没有完全使用 Ruby 2.7。谢谢!
      【解决方案6】:

      好吧,您可以尝试Module.constants(true),如here 所述,这可能比使用pry 优惠要多一点,但它会让您有机会窥视所涉及的模块

      【讨论】:

      • 不过,似乎没有办法从中找到源位置。
      猜你喜欢
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多