Ruby注释终极指南:提升代码可读性与维护性

引言

注释是计算机程序中被编译器和解释器忽略的行。你可以使用注释来使你的程序更易于其他程序员理解,通过提供更多关于程序的每个部分在做什么的上下文或解释。此外,你可以使用注释来解释为什么选择了特定的解决方案,甚至在你修复问题时临时阻止问题或不完整的程序部分的执行。

有些注释可能会永远留在代码中,例如解释上下文的注释,而其他注释可能是暂时性的,例如在构建程序时给自己留的注释。

让我们来看看如何在Ruby程序中使用注释来留下注记,以及如何将其作为调试工具使用。

注释语法和用法

在Ruby中,注释以井号(#)开始,并一直延续到行尾,就像这样:

# 这是Ruby中的一条注释

虽然不是必需的,但是为了提高注释的可读性,你应该在井号后放置一个空格。

当你运行一个程序时,你不会在代码中看到任何注释的指示;Ruby解释器完全忽略它们。注释在源代码中是给人类阅读的,而不是给计算机执行的。

在一个简单的Ruby程序中,就像在教程《如何编写你的第一个Ruby程序》中的那个一样,你可以使用注释来提供关于代码每个部分发生的详细信息。

问候.rb
# 向用户显示提示
puts "请输入您的姓名。"

# 保存用户输入并移除最后一个字符(回车键)
name = gets.chop

# 将输出打印到屏幕
puts "你好,#{name}!我是Ruby!"

这些注释可以让你对程序的每个部分以及其工作原理有一个大致的了解。

在一个遍历数组并将其内容显示为HTML列表的程序中,你可能会看到这样的注释,它们提供了关于代码更详细的解释。

鲨鱼.rb
sharks = ['锤头鲨', '大白鲨', '狗鲨', '皱鳃鲨', '牛头鲨', '真鲨']

# 将数组中的每个条目转换为HTML实体,带有前导空格和换行符。
listitems = sharks.map{ |shark| " <li>#{shark}</li>\n"}

# 打印开头的 <ul> 标签,然后打印列表项数组
print "<ul>\n#{listitems.join}</ul>"

你可能对像 mapjoin 这样的方法还不太熟悉,但是注释会让你明白这个程序应该如何工作以及输出可能会是什么样子。试试看吧。将这段代码放在一个名为 sharks.rb 的文件中并运行它。

  1. ruby sharks.rb

您将会看到程序的输出。

输出
<ul> <li>锤头鲨</li> <li>大白鲨</li> <li>狗鲨</li> <li>皱鳃鲨</li> <li>牛头鲨</li> <li>真鲨</li> </ul>

请注意到您看不到这些注释,因为解释器已经忽略了它们。但输出结果很可能和您期望的一样。注释是一种很好的沟通工具,尤其是对于刚开始学习这门语言的人来说。

注释应该和代码在同一水平缩进处进行。也就是说,没有缩进的类定义应该有无缩进的注释,而随后的每一个缩进层级都应该有与其所注释的代码对齐的注释。

例如,这里是一个魔法8球游戏的Ruby实现。计算机会对你提出的问题给出随机答案。请注意,每个部分的代码的缩进与注释的缩进水平相同。

魔球.rb
# Eightball 类代表了神奇的8号球。
class Eightball

# 设置可用的选项
def initialize
@choices = ["Yes", "No", "All signs point to yes", "Ask again later", "Don't bet on it"]
end

# 从可用选项中随机选择一个
def shake
@choices.sample
end
end

def play
puts "问问神奇的8号球你的问题吧。"

# 因为我们不需要用户的答案,所以不捕获它。
gets

# 创建一个神奇8号球的新实例并用它来获取答案。
eightball = Eightball.new
answer = eightball.shake
puts answer

# 提示重新开始游戏并评估答案。
puts "想再试一次吗?按 'y' 继续,按其他任意键退出。"
answer = gets.chop

if answer == 'y'
play
else
exit
end
end

# 开始第一局游戏。
play

注释应该帮助程序员,无论是原始开发者还是项目合作者。这意味着注释必须像代码一样得到维护。与代码相矛盾的注释比没有注释更糟糕。

当你刚开始编程时,你可能会写很多注释来帮助自己理解代码。但随着经验的增长,你应该将注释用于解释代码背后的“为什么”,而不是代码的“内容”或“如何实现”。除非代码特别复杂,通常通过查看代码就能知道代码在做什么或者如何实现。

例如,一旦你了解了Ruby,这种注释就没有那么有帮助了:

# 在屏幕上打印“Hello World”。
print "Hello World"

这条注释重申了代码已经实现的功能,虽然它不会影响程序的输出,但在阅读代码时却是多余的干扰。

有时候你可能需要写一些更详细的注释。这就是块注释的作用所在。

块注释

您可以使用块注释来解释更复杂的代码或者读者可能不熟悉的代码。这些较长的注释适用于随后的一些或全部代码,并且与代码保持相同的缩进级别。

在块注释中,每一行都以井号(#)开头,后面跟着一个空格以提高可读性。如果需要使用多个段落,它们应该用一行只包含一个井号的空行分隔开来。

以下是Sinatra网络框架源代码中块注释的示例。它向其他开发者提供了关于该特定代码如何工作的一些背景信息。

请查看以下网址,查阅关于Sinatra框架的核心文件:https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb

这是文章《如何在Ruby中使用注释》的第3部分(共4部分)。

...
# 一些Rack处理器(如Thin、Rainbows!)实现了扩展的body对象协议,然而,
# 某些中间件(特别是Rack::Lint)会因为没有镜像相关方法而破坏它。
# 这个中间件会检测到扩展的body对象,并确保它直接到达处理器。我们在这里这样做,
# 这样我们的中间件和应用程序设置的中间件仍然能够运行。
class ExtendedRack < Struct.new(:app)
def call(env)
result, callback = app.call(env), env['async.callback']
return result unless callback and async?(*result)
after_response { callback.call result }
setup_close(env, *result)
throw :async
end
...

当你需要详细解释代码片段时,块注释非常有用。然而,你应该尽量避免过度注释你的代码,因为那些注释可能是冗余的并且会增加额外的干扰。相信其他程序员能够理解 Ruby 代码,除非你是为特定的受众编写。注释应该增加上下文,而不是重复代码。

Ruby 有一种用于多行注释的替代语法,但很少被使用。下面是一个示例:

多行.rb

=begin
这是一个多行注释。
你可以使用这种方法让你的注释
跨越多行,而无需在每行开头放置井号。
=end

=begin=end 行必须位于行首,不能缩进。正因为如此,你很少会看到这种用法。

我们接下来看一下内联注释。

内联注释

行内注释出现在同一行的语句中,紧跟在代码后面。和其他注释一样,它们以井号开始,后面跟着一个空格字符以便阅读。

一般来说,内联注释看起来像这样:

[code] # 关于代码的内联注释

在代码中应该谨慎使用行内注释,但对于解释棘手或不明显的代码部分来说非常有效。如果您认为将来可能会忘记正在编写的代码行,或者正在与可能不熟悉代码所有方面的人合作,行内注释也是有用的。

例如,如果您在 Ruby 程序中没有使用很多数学,您或您的合作伙伴可能不知道以下代码创建了一个复数,因此您可能希望在此处添加一个内联注释进行说明。

a=Complex(4,3) # 创建复数 4+3i

你还可以使用内联注释来解释为什么要做某事。

pi = 3.14159 # 为了本程序,有意限制了pi的值。

必要时,应仅在需要并能为阅读程序的人提供有益指导的情况下使用行内注释。

注释代码以进行测试

除了使用注释来记录代码外,您还可以使用井号符号将不想执行的代码注释掉,以便在测试或调试当前创建的程序时使用。有时,当您在添加新代码行后出现错误时,您可能希望将其中一些注释掉,以通过逐一排除的方式进行故障排除。

例如,在魔法八球游戏中,或许你希望阻止游戏再次运行,因为你只关心代码是否正确评估答案。你可以注释掉重新开始游戏的那行代码。

八球.rb
...

# 提示用户重新开始游戏并评估答案。
puts "想再试一次吗?按 'y' 继续,按任意其他键退出。"
answer = gets.chop

if answer == 'y'
# 玩游戏
else
exit
end
end
...

注释还可以让您在编写代码实现解决方案时尝试替代方法。例如,在使用 Ruby 处理数组时,您可能希望尝试几种不同的方法。您可以使用注释来测试每种方法,并确定哪种方法最适合您。

鲨鱼.rb

sharks = ["Tiger", "Great White", "Hammerhead"]

# for shark in sharks do
# puts shark
# end

sharks.each do |shark|
puts shark
end

将代码注释掉可以让您尝试不同的编程方法,同时通过有序地注释和运行程序的部分来帮助您找出错误的源头。

结论

在您的 Ruby 程序中使用注释可以使程序对人类更具可读性,包括对您未来的自己。包含相关有用且适当的注释可以让他人更容易与您合作开发编程项目。当您在长时间之后重新访问您的项目时,它们也能帮助您理解您以前编写的代码。

bannerAds