Ruby的%q / %Q引用方法有什么用途?

74

我一直在阅读 Thomas 的《Programming Ruby 1.9》,并发现了替代的定界单引号和双引号方法(%q / %Q)。我也从其他 Ruby 语言参考资料中知道它们。

%q/I'm acting like a single-quoted string/

%Q|"I'm acting like a double-quoted string" --Anonymous|

我刚开始接触 Ruby,但在生产代码中我从未遇到过这种引用方法。

除了能够使用反斜杠避免内部转义引号的明显优点外,这种引用方式与普通单引号或双引号相比有哪些常见用途?它们通常用于单行还是多行字符串?如果用于多行字符串,它们是否比 HEREDOC 字符串更受欢迎?是否存在特定的 Ruby 习惯用法常见于其中?


4
我认为那就是使用情况。我只使用heredocs来表示多行字符串。 - Dave Newton
1
Heredocs 有一个很大的优点,就是你可以把引导部分放在代码链中,这样它就不会打破使用它的代码行,就像 str = <<-TEXT.lines.map(&:strip) ... - Niklas B.
1
//我没有长时间使用Ruby,但我从未在生产代码中遇到过这种引用方法。// 这个Ruby语言特性可以追溯到Perl。因此,你更有可能在当前或曾经是Perl开发人员的Ruby程序员中找到这个特性的使用。要查找多个示例,请搜索“Perl quotelike operator”。 - dreftymac
5个回答

115

当你已经“用完”引用方法时,它们非常有用,可以在其中使用JavaScript转义HTML:

link = %q[<a href="javascript:method('call')">link</a>]

我也发现在处理多行SQL语句时它们非常有用:

execute(%Q[
  INSERT INTO table_a (column_a)
    SELECT value
      FROM table_b
      WHERE key='value'
])
那里的优点是您不需要关注查询中使用的引号类型。它可以使用单引号、双引号或两者一起工作。它们也比HEREDOC样式方法更简单。Ruby提供了其他方便的方法,例如%r,它可以构造正则表达式。这避免了尝试编写处理诸如http://之类必须转义的内容时出现斜线疲劳的情况。

我之前没有考虑过的 JavaScript 示例是,内部引号的功能在语法上非常重要,这使得当前被引用和转义的上下文(标记属性、JS 字符串或整个外部字符串)变得混淆不清。 - Michael Berkowski
HEREDOC风格在声明变量时还可以,但是当用作方法参数时非常丑陋,尤其是当您尝试将它们作为不同参数提供时。对于未经训练的人来说,它们相当令人困惑。 - tadman

12

概述

除了“避免在引号内部转义”和@tadman提供的示例之外,还有其他用例:

  • 在与生成程序本身相同语言的情况下自动生成代码(例如,Ruby生成Ruby)
  • 提供干净格式化的代码,不会让文本编辑器的语法突出显示功能混淆
  • 允许存储可能必须通过多个存储层(例如与网站交互的数据库,与文本编辑器交互的片段管理系统,与子shell交互等)的代码块

详细信息

这种方法是一种通用且强大的习惯用语,适用于任何自动化代码生成工具,包括但不限于编写其他语言中样板代码的工具,或为IDE或文本编辑器管理代码片段的工具。

除了@tadman已经提供的示例之外,还有一般情况下要生成代码而被生成的代码与生成程序的代码相同或基本相似的情况。

在这些情况下,该解决方案所起的作用远不止帮助避免使用反斜杠来转义引号。如果没有像这样的解决方案,有些情况下生成的代码可能会变得极其难以维护。

要查看示例,请随时查看以下参考资料。

参考资料

[例如,见

]


5

我知道这是一个老帖子,但是当调用system命令并想要插入一些值时,我已经在生产环境中使用它们了,就像这样:

 system(%Q(ffmpeg -y -i "#{input_filepath}" -qscale:a 2 "#{output_filepath}"))

非常方便。

3
值得注意的是,在生成gemspec时,bundler和jeweler默认使用%q来填写gemspec的摘要/描述部分。这可以防止某人在摘要或描述中使用引号而破坏gemspec。

-1

当你的字符串包含单引号或双引号时,转义字符就显得特别有用。虽然这种情况不是经常发生,但技巧非常实用。


1
楼主说他想知道除了“避免内部转义引号”之外的其他方法。 - xdazz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接