有什么办法能让这看起来好一点吗?
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'
比如,有没有办法暗示串联?
有什么办法能让这看起来好一点吗?
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'
比如,有没有办法暗示串联?
当前回答
这个问题让我开始理解HEREDOC是如何工作的。如果答案太长,请原谅。
当你想定义带有换行符和适当缩进的多行字符串(Ruby 2.3起可用)时,你需要使用弯曲的HEREDOC <<~:
conn.exec <<~EOS
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
EOS
# -> "select...\nfrom...\nwhere..."
如果不考虑适当的缩进,那么单引号和双引号可以在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"
# -> "select...\n from...\n where..."
如果单引号或双引号很麻烦,因为这需要大量的转义,那么百分比字符串文字符号%是最灵活的解决方案:
conn.exec %(select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc
where (ProductLine = 'R' OR ProductLine = "S") AND Country = "...")
# -> "select...\n from...\n where..."
如果目的是避免换行(扭曲的HEREDOC、引号和百分比字符串文字都会导致换行),那么可以通过将反斜杠\作为行中最后一个非空格字符来使用行接续。这将继续这一行,并将导致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'
# -> "select...from...where..."
如果使用Rails,则使用String。Squish将剥离字符串的开头和结尾空格,并将所有连续的空格(换行符、制表符和所有空格)折叠为一个空格:
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".squish
# -> "select...attr7 from...etc, where..."
更多的细节:
Ruby HEREDOC语法
这里的字符串文档符号是一种在代码中指定长文本块的方法。它由<<开始,后面跟着一个用户定义的字符串(字符串结束符)。接下来的所有行都被连接起来,直到在一行的开始处找到字符串结束符:
puts <<HEREDOC
Text Text Text Text
Bla Bla
HEREDOC
# -> "Text Text Text Text\nBlaBla"
字符串结束符可以自由选择,但通常使用类似“EOS”(字符串结束符)或匹配字符串域的东西,如“SQL”。
HEREDOC默认支持插值,或者当EOS结束符被双引号括起来时:
price = 10
print <<"EOS" # comments can be put here
1.) The price is #{price}.
EOS
# -> "1.) The price is 10."
如果EOS结束符是单引号,则可以禁用插值:
print <<'EOS' # Disabled interpolation
3.) The price is #{price}.
EOS
# -> "3.) The price is #{price}."
<<HEREDOC的一个重要限制是String结束符必须在行首:
puts <<EOS
def foo
print "foo"
end
EOS
EOS
#-> "....def foo\n......print "foo"\n....end\n..EOS"
为了解决这个问题,我们创建了<<-语法。它允许EOS终止符缩进以使代码看起来更好。<<-和EOS结束符之间的行仍然完整地使用,包括所有缩进:
def printExample
puts <<-EOS # Use <<- to indent End of String terminator
def foo
print "foo"
end
EOS
end
# -> "....def foo\n......print "foo"\n....end"
从Ruby 2.3开始,我们现在有了弯弯曲曲的HEREDOC <<~,它删除了前导空格:
puts <<~EOS # Use the squiggly HEREDOC <<~ to remove leading whitespace (since Ruby 2.3!)
def foo
print "foo"
end
EOS
# -> "def foo\n..print "foo"\nend"
空行和只包含制表符和空格的行将被<<~忽略
puts <<~EOS.inspect
Hello
World!
EOS
#-> "Hello\n..World!"
如果同时使用制表符和空格,则制表符被认为等于8个空格。 如果缩进最少的行位于制表符的中间,则不会删除该制表符。
puts <<~EOS.inspect
<tab>One Tab
<space><space>Two Spaces
EOS
# -> "\tOne Tab\nTwoSpaces"
HEREDOC可以做一些疯狂的事情,比如使用反撇号执行命令:
puts <<`EOC`
echo #{price}
echo #{price * 2}
EOC
字符串定义可以“堆叠”,这意味着第一个EOS终止符(下面的EOSFOO)将结束第一个字符串,并开始第二个字符串(下面的EOSBAR):
print <<EOSFOO, <<EOSBAR # you can stack them
I said foo.
EOSFOO
I said bar.
EOSBAR
我不认为有人会这样使用它,但<<EOS实际上只是一个字符串文字,可以放在字符串通常可以放在的地方:
def func(a,b,c)
puts a
puts b
puts c
end
func(<<THIS, 23, <<THAT)
Here's a line
or two.
THIS
and here's another.
THAT
如果你没有Ruby 2.3,但是Rails >= 3.0,那么你可以使用String。Strip_heredoc,它的作用与<<~相同
# File activesupport/lib/active_support/core_ext/string/strip.rb, line 22
class String
def strip_heredoc
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
end
end
puts <<-USAGE.strip_heredoc # If no Ruby 2.3, but Rails >= 3.0
This command does such and such.
Supported options are:
-h This message
...
USAGE
故障排除
如果在Ruby解析文件时看到错误,那么很有可能是使用了herdoc的额外前导或尾随空格,或者使用了弯弯曲曲的HEREDOC的额外尾随空格。例如:
你看到了什么:
database_yml = <<~EOS
production:
database: #{fetch(:user)}
adapter: postgresql
pool: 5
timeout: 5000
EOS
Ruby告诉你:
SyntaxError: .../sample.rb:xx: can't find string "EOS" anywhere before EOF
...sample.rb:xx: syntax error, unexpected end-of-input, expecting `end'
错在哪里:
找出终止EOS后的额外空格。
百分比字符串字面量
请参阅RubyDoc了解如何使用百分比符号后面的字符串括号对,如%(…),%[…), %{…}等,或任意一对非字母数字字符,如%+…+
最后一句话
最后,要得到原始问题“是否有一种方法可以暗示连接?”的答案。 Ruby总是暗示如果两个字符串(单引号和双引号)背靠背地找到:
puts "select..." 'from table...' "where..."
# -> "select...from table...where..."
需要注意的是,这不能跨换行,因为Ruby正在解释语句的结束,而一行中仅包含字符串的后续行不会执行任何操作。
其他回答
今天的优雅回答:
<<~TEXT
Hi #{user.name},
Thanks for raising the flag, we're always happy to help you.
Your issue will be resolved within 2 hours.
Please be patient!
Thanks again,
Team #{user.organization.name}
TEXT
<<-TEXT和<<~TEXT有区别,前者保留了块内的空格,后者则没有。
还有其他的选择。 比如串联等等,但这个更有意义。
如果我错了,请告诉我…
是的,如果你不介意额外的换行被插入:
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'
你也可以使用heredoc:
conn.exec <<-eos
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
eos
你也可以使用双引号
x = """
this is
a multiline
string
"""
2.3.3 :012 > x
=> "\nthis is\na multiline\nstring\n"
如果需要删除换行符“\n”,请在每行末尾使用反斜杠“\”
最近,随着Ruby 2.3的新特性,新的弯弯曲曲的HEREDOC将允许您以一种非常好的方式编写多行字符串,并且只需要进行最小的更改,因此,将它与.squish(如果您正在使用rails)结合使用将使您以一种非常好的方式编写多行字符串! 在只使用ruby的情况下,您可以执行<<~SQL.split。Join(" "),几乎相同
[1] pry(main)> <<~SQL.squish
[1] pry(main)* select attr1, attr2, attr3, attr4, attr5, attr6, attr7
[1] pry(main)* from table1, table2, table3, etc, etc, etc, etc, etc,
[1] pry(main)* where etc etc etc etc etc etc etc etc etc etc etc etc etc
[1] pry(main)* SQL
=> "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"
裁判:https://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
conn.exec = <<eos
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
eos