【问题标题】:Where can I find an actively developed lint tool for Ruby?我在哪里可以找到积极开发的 Ruby lint 工具?
【发布时间】:2023-04-04 04:12:02
【问题描述】:

我编写的大部分代码都是用 Ruby 编写的,而且每隔一段时间,我就会犯一些错字,但过一会儿才会被发现。当我让我的脚本运行长任务时,这很烦人,然后返回发现我有一个错字。

是否有积极开发的 Ruby lint 工具可以帮助我克服这个问题?是否可以在处理大量源文件(其中一些是动态加载的)的系统中使用它?

以这个sn-p为例:

a = 20
b = 30
puts c

要赢得赏金,请向我展示一个工具,该工具将检测 c 变量为未创建/未定义。

【问题讨论】:

  • 你知道那个程序不会运行吗? Ruby 将为 main:Object (NameError)` 发出 test.rb:1: undefined local variable or method c'。看来您应该在没有 lint 工具的情况下很快发现这些错误。
  • 你知道这是一个例子吗?那个 Ruby 在 RUNTIME 发现了这个问题?
  • 你在 3 年前问过这个问题。现在使用 Ruby 2.0,您可以执行“ruby -wc”,它也会给您警告。在您的情况下,它会警告您未使用“a”和“b”。但它不会警告您使用“c”(因为它不应该)。
  • ...还有'ruby-lint',看起来还不错。
  • @NiccoloM。 ruby-lint 似乎是一个很好的答案。发布为答案,我会 +1。或者,如果您愿意,我可以将其发布为社区 wiki。

标签: ruby code-analysis static-analysis lint


【解决方案1】:
  • ruby -c myfile.rb 将检查正确的 Ruby 语法。
  • Reek 检查 Ruby 代码中常见的代码异味。
  • Roodi 检查 Ruby 代码中常见的面向对象设计问题。
  • Flog 可以警告您异常复杂的代码。

[Plug] 如果您的项目位于公共 Github 存储库中,Caliper 可以在您每次提交时在您的代码上运行后三个工具和其他工具。 (免责声明:我在 Caliper 上工作)

【讨论】:

  • 它们中的任何一个都可以检测到变量名中的拼写错误吗?
  • 我在我提供的 sn-p 上运行了 Reek、Roodi 和 Flog,但他们都没有说 c 变量有什么问题。
  • 欢迎来到动态语言的世界。您获得了极大的灵活性,但您失去了对代码进行静态断言的能力,例如“我引用的所有符号在运行时都有效”。这是一个权衡。也就是说,我认为最近的一些 IDE 试图识别这样的错误。您可能会查看 RubyMine 或 Netbeans。就个人而言,我同意之前的评论者的观点,即你最好的选择是单元测试。如果您想快速收到错误通知,请使用 Autotest 之类的工具来不断运行您的测试。
  • 为了进一步解释,c 在这一点上可能指的是局部变量;在封闭词法范围中定义的变量;实例方法;单例方法;在超类或模块中定义的方法......等等。工具无法确定c 是无效的,因此在没有实际运行代码的情况下会出现拼写错误——这让我们回到了单元测试。
  • 为了评估代码,你需要一些东西来调用它。这叫做测试。
【解决方案2】:

看看RuboCop。它是一个基于Ruby Style Guide 的Ruby 代码样式检查器。它维护得非常积极,并支持所有主要的 Ruby 实现。它适用于 Ruby 1.9 和 2.0,并具有出色的 Emacs 集成。

【讨论】:

    【解决方案3】:

    Pelusa 很好,但仅在 rubinius 中工作。不过,对于熟悉 RVM 的人来说,这不应该成为问题。

    【讨论】:

      【解决方案4】:

      尚未使用它,但听起来很有希望(我测试后会更新)。

      https://github.com/michaeledgar/laser

      Ruby 代码的静态分析和样式 linter。

      【讨论】:

        【解决方案5】:

        nitpick 可能就是您要找的。​​p>

        使用此代码:

        class MyString < String
          def awesome
            self.gsub("e", "3").gsub("l", "1").uppercase
          end
        end
        
        puts MyString.new("leet").awesome
        

        ...它输出:

        $ nitpick misspelling.rb 
        *** Nitpick had trouble loading "misspelling.rb":
            NoMethodError undefined method `uppercase' for "133t":MyString
        Nothing to report boss! He's clean!
        

        【讨论】:

          【解决方案6】:

          你可以试试Diamondback Ruby。它会对 Ruby 代码进行静态类型检查,因此会责怪您使用未定义的变量。

          虽然 DRuby 是一个正在进行的研究项目,但它已经非常适用于小型、自包含的 Ruby 脚本。目前,它无法分析“开箱即用”的大部分 Ruby 标准库。目前他们正在努力输入 Ruby on Rails(请参阅他们的 most recent papers)。

          【讨论】:

          • 看起来响尾蛇红宝石自 2009 年以来就没有更新过。:(
          【解决方案7】:

          RubyMine (http://www.jetbrains.com/ruby) 成功了:

          alt text http://img707.imageshack.us/img707/5688/31911448.png

          以下任何一项都无法完成 RubyMine 所做的所有分析。

          • NetBeans Ruby 包
          • Aptana RadRails
          • gVIM(带有 scrooloose 的合成插件)

          每一个都能够识别语法错误,例如括号数量错误、defs 过多、结尾、大括号等。但是没有一个能够像 RubyMine 那样识别无效的方法调用。

          原因如下:这很困难。

          由于 Ruby 非常动态(并且可以很容易地动态生成诸如“c”之类的方法),任何试图识别不存在的变量/方法的编辑器都需要加载整个环境的很大一部分,并且需要多个程序流程路径不断测试以获得准确的“有效性”结果。这比在几乎所有编程都是静态的 Java 中要困难得多(至少在我丢掉那顶帽子的时候是这样)。

          这种轻松地动态生成方法的能力是社区对测试如此推崇的原因之一。我真的建议您也尝试测试。

          【讨论】:

          • 同意。即使在这种情况下,如果您调用 ruby​​ -rfoo a.rb,代码也可能有效,其中 foo 定义了顶级 c 方法!
          • 我同意您的回复,但 RubyMine 是一个完整的 IDE。我只需要它的一个功能。
          • 酷酷...如果您真的有动力,您可以下载 IntelliJ 的 Ruby 插件(我理解它是开源的)并提取执行该处理的部分。但是使用 ParseTree 创建自己的解析器可能更容易:-)
          【解决方案8】:
          avdi@lazarus:~$ irb
          >> a = 20
          => 20
          >> b = 30
          => 30
          >> puts c
          NameError: undefined local variable or method `c' for main:Object
                  from (irb):3
          >>
          

          好了,这个工具叫做“IRB”。我得到赏金了吗?

          我只是在开玩笑。我写了第二个答案,希望能够让大家明白,在 Ruby 中,如果你想知道是否定义了某些东西,你必须运行代码

          【讨论】:

          • 让我们等一下,在你得到赏金之前:)
          • 嗯,不只是 irb,它是 Ruby。当您尝试访问未分配的变量时,Ruby 会发出警告。
          【解决方案9】:

          是的。 Test::Unit

          好的,我知道你已经知道这一点,从某种意义上说,这是一个没有帮助的答案,但你确实提出了鸭子打字的负面后果,那就是(目前)没有办法只是编写比 Java 可能需要的测试更多的测试。

          因此,作为记录,请参阅 Ruby 标准库或其他测试框架之一中的 Test::Unit

          拥有可以运行和重新运行的单元测试是捕获错误的最佳方式,并且您确实需要在 Ruby 等动态语言中使用更多的单元测试(测试,而不是错误 :-)...

          【讨论】:

          • 我知道测试是件好事 :)。我只想有一些现成的东西可以运行,并告诉我是否有拼写错误或异常糟糕的代码。 pylint logilab.org/857 之类的东西。
          • 我想我同意它会很有用。唯一的问题是,人们经常故意将不同的类型传递给一个方法。想象一下f x=nil;...;end; f(1);
          • 我看不出你需要更多动态语言的理由。编译器只能解决无数可能发生的错误之一。
          • 想象一个复杂软件系统的生命周期。最终,一些主要的东西会被重构。使用 Java,这可以放心地完成。在这个过程结束时,每个人都期待他们实际得到的类型。在 Ruby 中,可能有任意数量的意外类型等待动态传递,即使根本没有任何重构。这是支持静态类型的传统智慧和常见论点。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多