Ruby:我可以编写没有连接的多行字符串吗?
有没有办法让这个看起来好一点?
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7 ' +
'from table1, table2, table3, etc, etc, etc, etc, etc, ' +
'where etc etc etc etc etc etc etc etc etc etc etc etc etc'
比如,有没有办法暗示串联?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
这个答案的一些部分帮助我得到了我需要的东西(简单的多行串联,没有额外的空格),但由于没有一个实际的答案有它,我在这里编译它们:
作为奖励,这里有一个使用有趣的版本HEREDOC 语法(通过 此链接):
后者主要适用于情况这需要处理过程具有更大的灵活性。我个人不喜欢它,它把处理放在字符串的一个奇怪的地方(即在它前面,但使用通常在后面的实例方法),但它就在那里。请注意,如果您要缩进最后一个
END_SQL
标识符(这很常见,因为这可能位于函数或模块内部),则需要使用连字符语法(即p < ;<-END_SQL
而不是p <)。否则,缩进空格会导致标识符被解释为字符串的延续。
这并不能节省太多打字时间,但对我来说,它看起来比使用 + 符号更好。
另外(我在几年后的编辑中说过),如果您使用 Ruby 2.3+,则运算符 <<~ 也可用,它可以从最终字符串中删除额外的缩进。在这种情况下,您应该能够删除
.gsub
调用(尽管它可能取决于起始缩进和您的最终需求)。编辑:再添加一个:
There are pieces to this answer that helped me get what I needed (easy multi-line concatenation WITHOUT extra whitespace), but since none of the actual answers had it, I'm compiling them here:
As a bonus, here's a version using funny HEREDOC syntax (via this link):
The latter would mostly be for situations that required more flexibility in the processing. I personally don't like it, it puts the processing in a weird place w.r.t. the string (i.e., in front of it, but using instance methods that usually come afterward), but it's there. Note that if you are indenting the last
END_SQL
identifier (which is common, since this is probably inside a function or module), you will need to use the hyphenated syntax (that is,p <<-END_SQL
instead ofp <<END_SQL
). Otherwise, the indenting whitespace causes the identifier to be interpreted as a continuation of the string.This doesn't save much typing, but it looks nicer than using + signs, to me.
Also (I say in an edit, several years later), if you're using Ruby 2.3+, the operator <<~ is also available, which removes extra indentation from the final string. You should be able to remove the
.gsub
invocation, in that case (although it might depend on both the starting indentation and your final needs).EDIT: Adding one more:
在 ruby 2.0 中,您现在可以只使用
%
例如:
In ruby 2.0 you can now just use
%
For example:
是的,如果您不介意插入额外的换行符:
或者您可以使用 heredoc:
Yes, if you don't mind the extra newlines being inserted:
Alternatively you can use a heredoc:
这个问题让我深入了解 HEREDOC 的工作原理。如果答案太长,请原谅。
squiggly HEREDOC
<<~
是您想要定义多行字符串时要查找的内容带有换行符和适当的缩进(自 Ruby 2.3 起可用):如果不关心适当的缩进,那么单引号和双引号可以在 Ruby 中跨越多行:
如果单引号或双引号很麻烦因为这需要大量转义,那么 百分比字符串文字表示法
%
是最灵活的解决方案:如果目标是避免换行符(即波浪形的 HEREDOC,引号和百分比字符串文字会导致),然后可以通过将反斜杠
\
作为行中的最后一个非空白字符来使用行继续。这将继续该行,并导致 Ruby 将字符串背靠背连接(注意带引号的字符串内的空格):如果您使用 Rails,则
String.squish
将剥离字符串前导空格和尾随空格,并将所有连续空格(换行符、制表符等)折叠成一个空格:更多详细信息:
Ruby HEREDOC 语法
字符串的此处文档表示法 是一种指定长文本块的方法内联在代码中。它以
<<
开头,后跟用户定义的字符串(字符串结尾终止符)。以下所有行都将连接起来,直到在行的最开头找到字符串结尾终止符:字符串结尾终止符可以自由选择,但通常使用类似“EOS”(字符串结尾)或与字符串域匹配的内容,例如“SQL”。
HEREDOC 默认支持 插值 或当 EOS 终止符是双引号时:
如果 EOS 终止符是单引号,则可以禁用插值:
< 的一个重要限制是字符串结束符必须位于开头行的要点:
为了解决这个问题,创建了
<<-
语法。它允许 EOS 终止符缩进以使代码看起来更好。<<-
和 EOS 终止符之间的线条仍然完整地使用,包括所有缩进:从 Ruby 2.3 开始,我们现在有了波浪形的 HEREDOC
<<~ 删除前导空格:
<<~ 会忽略空行以及仅包含制表符和空格的行。
如果同时使用制表符和空格,则制表符被视为等于 8 个空格。
如果缩进最少的行位于选项卡的中间,则不会删除该选项卡。
HEREDOC 可以做一些疯狂的事情,例如使用反引号执行命令:
HEREDOC 字符串定义可以“堆叠”,这意味着第一个 EOS 终止符(下面的 EOSFOO)将结束第一个字符串并开始第二个字符串(下面的 EOSBAR):
我不'我认为没有人会这样使用它,但是
< 实际上只是一个字符串文字,可以放在通常可以放置字符串的任何位置:
如果您没有 Ruby 2.3 ,但 Rails
>=
3.0 则可以使用String.strip_heredoc
,其作用与<<~
故障排除
如果您看到错误当 Ruby 解析您的文件时,很可能您在 HEREDOC 中存在额外的前导或尾随空格,或者在波形 HEREDOC 中存在额外的尾随空格。例如:
您看到的内容:
Ruby 告诉您的内容:
问题所在:
发现终止 EOS 后的多余空格。
百分比字符串文字
请参阅 RubyDoc 了解如何使用百分比字符串文字。百分比字符串文字以百分号
%
开头,后跟左括号或任何非字母数字字符。然后,输入字符串并以关联的右括号符号或非字母数字字符结束字符串文字。因此,您可以使用
%(...)
、%[...]
、%{...}
或例如%+...+
。无论使用哪种符号或括号(圆形、方形、花形),结果始终相同:只是一个字符串文字。
您只需选择内部字符串中最不可能使用的终止符,从而减少转义的需要。例如,在 SPARQL 查询中
{}
和()
以及[]
都被使用,因此使用% 可能是有意义的$...$
。在 SQL 中,[]
和()
很常见,因此%{}
可能是一个不错的选择。最后的话
最后,为了得到最初问题“有没有办法暗示串联?”的答案。
回答:如果两个字符串(单引号和双引号)被发现背对背,Ruby 总是意味着串联:
需要注意的是,这不能跨换行符工作,因为 Ruby 正在解释语句的结尾以及仅由字符串组成的后续行在线上没有做任何事情。
This question made me go off a rabbit hole to understand how HEREDOC works. Excuse me if the answer became too long.
The squiggly HEREDOC
<<~
is what you are looking for when you want to define a multi-line string with newlines and proper indentation (available since Ruby 2.3):If proper indentation is not a concern, then single and double quotes can span multiple lines in Ruby:
If single or double quotes are cumbersome because that would need lots of escaping, then the percent string literal notation
%
is the most flexible solution:If the aim is to avoid the newlines (which both the squiggly HEREDOC, quotes and the percent string literal will cause), then a line continuation can be used by putting a backslash
\
as the last non-whitespace character in a line. This will continue the line and will cause Ruby to concatenate the Strings back to back (watch out for those spaces inside the quoted string):If you use Rails, then
String.squish
will strip the string of leading and trailing space and collapse all consecutive whitespaces (newlines, tabs, and all) into a single space:More details:
Ruby HEREDOC Syntax
The Here Document Notation for Strings is a way to designate long blocks of text inline in code. It is started by
<<
followed by a user-defined String (the End of String terminator). All following lines are concatenated until the End of String terminator is found at the very beginning of a line:The End of String terminator can be chosen freely, but it is common to use something like "EOS" (End of String) or something that matches the domain of the String such as "SQL".
HEREDOC supports interpolation by default or when the EOS terminator is double quoted:
Interpolation can be disabled if the EOS terminator is single quoted:
One important restriction of the
<<HEREDOC
is that the End of String terminator needs to be at the beginning of the line:To get around this, the
<<-
syntax was created. It allows the EOS terminator to be indented to make the code look nicer. The lines between the<<-
and EOS terminator are still used in their full extend including all indentation:Since Ruby 2.3, we now have the squiggly HEREDOC
<<~
which removes leading whitespace:Empty lines and lines which only contains tabs and space are ignored by <<~
If both tabs and spaces are used, tabs are considered as equal to 8 spaces.
If the least-indented line is in the middle of a tab, this tab is not removed.
HEREDOC can do some crazy stuff such as executing commands using backticks:
HEREDOC String definitions can be "stacked", which means that the first EOS terminator (EOSFOO below) will end the first string and start the second (EOSBAR below):
I don't think anybody would ever use it as such, but the
<<EOS
is really just a string literal and can be put whereever a string can normally be put:If you don't have Ruby 2.3, but Rails
>=
3.0 then you can useString.strip_heredoc
which does the same as<<~
Troubleshooting
If you see errors when Ruby parses your file, then it is most likely that you either have extra leading or trailing spaces with a HEREDOC or extra trailing spaces with a squiggly HEREDOC. For example:
What you see:
What Ruby tells you:
What is at fault:
Spot the extra spaces after the terminating EOS.
Percent String Literals
See RubyDoc for how to use the percentage string literals. Percentage string literals start with a percentage sign
%
followed either an opening parenthesis or any non-alphanumeric character. Then you put your string and end the string literal with the associated closing parenthesis symbol or the non-alphanumeric character.Thus you could use
%(...)
,%[...]
,%{...}
or e.g.%+...+
.No matter which symbol or parentheses (round, square, curly) the result is always the same: Just a string literal.
You simply chose the terminators that are the least likely to be used in the string inside, reducing the need to do escaping. For example, in SPARQL queries
{}
and()
and[]
are all used, so it might make sense to use%$...$
. In SQL,[]
and()
are common, thus%{}
could be a good pick.Last Words
Last, to get the answer to the original question "Is there a way to imply concatenation?"
answered: Ruby always implies concatenation if two strings (single and double quoted) are found back to back:
The caveat is that this does not work across line-breaks, because Ruby is interpreting an end of statement and the consequitive line of just strings alone on a line doesn't do anything.
正如您已经阅读过的,多行字符串有多种语法。我最喜欢的是 Perl 风格:
多行字符串以 %q 开头,后跟 {、[ 或 (,然后以相应的反转字符终止。%q 不允许插值;%Q 允许插值,因此您可以编写内容像这样:
我实际上不知道如何调用这些类型的多行字符串,所以我们将它们称为 Perl 多行。
但是请注意,无论您使用 Perl 多行还是 Mark 和 Peter 建议的heredocs,您最终都会得到潜在的结果。不必要的空格。在我的示例和它们的示例中,“from”和“where”行都包含前导空格,因为它们在代码中缩进。如果不需要此空格,则必须像现在一样使用连接字符串。
There are multiple syntaxes for multi-line strings as you've already read. My favorite is Perl-style:
The multi-line string starts with %q, followed by a {, [ or (, and then terminated by the corresponding reversed character. %q does not allow interpolation; %Q does so you can write things like this:
I actually have no idea how these kinds of multi-line strings are called so let's just call them Perl multilines.
Note however that whether you use Perl multilines or heredocs as Mark and Peter have suggested, you'll end up with potentially unnecessary whitespaces. Both in my examples and their examples, the "from" and "where" lines contain leading whitespaces because of their indentation in the code. If this whitespace is not desired then you must use concatenated strings as you are doing now.
有时值得删除换行符
\n
例如:Sometimes is worth to remove new line characters
\n
like:您还可以使用双引号
如果需要删除换行符“\n”,请在每行末尾使用反斜杠“\”
You can also use double quotes
If needed to remove line breaks "\n" use backslash "\" at the end of each line
其他选项:
Other options:
最近,随着 Ruby 2.3 中的新功能的出现,新的
squiggly HEREDOC
可以让您以最小的更改以良好的方式编写多行字符串,因此将其与.squish
结合使用(如果您使用的是 Rails)将让您以一种很好的方式编写多行!如果仅使用 ruby,您可以执行
<<~SQL.split.join(" ")
,这几乎相同的参考: https:// infinum.co/the-capsized-8/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
Recently with the new features in Ruby 2.3 the new
squiggly HEREDOC
will let you write our multiline strings in a nice manner with a minimal change so using this combined with the.squish
(if you are using rails) will let you write multiline in a nice way!in case of just using ruby, you can do a
<<~SQL.split.join(" ")
which is almost the sameref: https://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
为了避免关闭每行的括号,您可以简单地使用带反斜杠的双引号来转义换行符:
To avoid closing the parentheses for each line you can simply use double quotes with a backslash to escape the newline:
今天的优雅答案:
<<-TEXT
和<<~TEXT
之间有区别,前者保留块内的间距,后者则不保留。还有其他选择。
就像串联等一样,但这通常更有意义。
如果我在这里错了,请告诉我如何......
Elegant Answer Today:
Theres a difference in
<<-TEXT
and<<~TEXT
, former retains the spacing inside block and latter doesn't.There are other options as well.
Like concatenation etc. but this one makes more sense in general.
If I am wrong here, let me know how...
<<是字符串的连接运算符
<< is the concatenation operator for strings
如果您确实介意额外的空格和换行符,您可以使用
(使用 %W 来插入字符串)
If you do mind extra spaces and newlines, you can use
(use %W for interpolated strings)
与此处文档和长字符串相比,此建议的优点是自动缩进器可以适当缩进字符串的每个部分。但这是以效率为代价的。
This suggestion has the advantage over here-documents and long strings that auto-indenters can indent each part of the string appropriately. But it comes at an efficiency cost.
和您一样,我也在寻找不包含换行符的解决方案。 (虽然它们在 SQL 中可能是安全的,但在我的情况下并不安全,而且我有一大段文本要处理)
这可以说是同样丑陋,但您可以在定界文档中使用反斜杠转义换行符来省略它们结果字符串:
请注意,如果没有插值,则无法得出此结果(IE
<<~'END_OF_INPUT'
),因此请小心。#{expressions}
将在此处进行计算,而它们不会在您的原始代码中进行计算。 A.由于这个原因,威尔逊的答案可能更好。Like you, I was also looking for a solution which does not include newlines. (While they may be safe in SQL, they're not safe in my case and I have a large block of text to deal with)
This is arguably just as ugly, but you can backslash-escape newlines in a heredoc to omit them from the resulting string:
Note that you cannot due this without interpolation (I.E.
<<~'END_OF_INPUT'
) so be careful.#{expressions}
will be evaluated here, whereas they will not in your original code. A. Wilson's answer may be better for that reason.