这些字符串被称为什么?什么是Squish?Ruby。

24

我找到了这段代码:

sql = <<-SQL.squish
        UPDATE #{klass.constantize.table_name}
           SET uuid = uuid_generate_v4(), updated_at = now()
         WHERE id IN (#{group.map(&:id).join(',')})
           AND uuid IS NULL
      SQL

这里发生了什么?我猜这是一种特殊的字符串定界符。它叫什么?它是Ruby特有的吗?squish 是做什么的?


2
请参考 这里 中的 squish 方法,关于它的实现方式以及查询中使用的硬编码表名,我认为这不是最好的做法。 - Sebastián Palma
2个回答

23

这是一个Ruby语言中的多行字符串语法,被称为Here Document(这里文档,HereDoc)。

例如:

sql = <<-SQL
        UPDATE #{klass.constantize.table_name}
           SET uuid = uuid_generate_v4(), updated_at = now()
         WHERE id IN (#{group.map(&:id).join(',')})
           AND uuid IS NULL
      SQL

将为您提供一个名为sql的字符串变量,其值字面上为:

         UPDATE #{klass.constantize.table_name}
           SET uuid = uuid_generate_v4(), updated_at = now()
         WHERE id IN (#{group.map(&:id).join(',')})
           AND uuid IS NULL

保留所有空格和换行符。

来自HereDoc文档:

要在HereDoc上调用方法,请将其放置在开头标识符之后

这个引用的一个常见用法是当你有一个很长的字符串,你不想把它写在一行上,因此使用HereDoc,但你仍然不想保留HereDoc保存的所有换行符和空格,这种情况下,你可以只需调用squish(这是Rails添加的方法)来删除它们。例如:

sql = <<-SQL.squish
        UPDATE #{klass.constantize.table_name}
           SET uuid = uuid_generate_v4(), updated_at = now()
         WHERE id IN (#{group.map(&:id).join(',')})
           AND uuid IS NULL
      SQL

将会给你一个sql字符串变量,其值字面上为:

UPDATE #{klass.constantize.table_name} SET uuid = uuid_generate_v4(), updated_at = now() WHERE id IN (#{group.map(&:id).join(',')}) AND uuid IS NULL

将所有换行符和空格压缩成一个空格。


这是最令人困惑的。在第二个分隔符上添加该方法会更有意义,我认为。但它引发了 SyntaxError,因为它正在寻找 SQL 并发现了 SQL.squish。这种情况有点奇怪,因为它能够以一种方式工作但另一种方式则不行。 - Eric Duminil
@EricDuminil 没错,这就是将方法调用添加到开头标识符而不是结尾标识符的原因。 - Tamer Shlash
1
@EricDuminil:据我所知,您可以在字符串内部使用它。分隔符仅在行的开头被识别。 - Jörg W Mittag
可能是因为原始的SQL正在被下一行开始直到分隔符的所有内容所替换,然后在替换中调用了squish。如果它在结束分隔符上,它可能会被忽略,或解释为下一个块。 - Elliott de Launay
1
@TamerShlash @EricDuminil 它识别SQL是一个heredoc分隔符,而不是一个变量名,因为它紧跟着<<-。分隔符可以是任何东西,只要以这个开头,比如<<-DESCRIPTION,然后字符串的内容从下一行开始,直到看到一个只有分隔符的行为止(这就是为什么方法调用不能在最后一个分隔符上,但可以在第一个上,因为内容直到第一个分隔符之后的行才开始)。 - undefined
显示剩余4条评论

6

String#squish 来自 Rails,表示内联字符串没有多个 \n\s。 从文档中了解:

返回字符串,首先删除字符串两端的所有空格,然后将剩余的连续空格组合成一个空格。


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