有没有办法让这个看起来更好一点?
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'
是的,有没有办法暗示连接?
答案 0 :(得分:528)
这个答案有些东西可以帮助我得到我需要的东西(简单的多行连接,没有额外的空格),但由于没有任何实际的答案,我在这里编译它们:
str = 'this is a multi-line string'\
' using implicit concatenation'\
' to prevent spare \n\'s'
=> "this is a multi-line string using implicit concatenation to eliminate spare
\\n's"
作为奖励,这是使用有趣的HEREDOC语法的版本(通过this link):
p <<END_SQL.gsub(/\s+/, " ").strip
SELECT * FROM users
ORDER BY users.id DESC
END_SQL
# >> "SELECT * FROM users ORDER BY users.id DESC"
后者主要用于需要处理更灵活的情况。我个人不喜欢它,它把处理放在一个奇怪的地方w.r.t.字符串(即在它前面,但使用通常后来的实例方法),但它就在那里。请注意,如果要缩进最后一个END_SQL
标识符(这很常见,因为这可能在函数或模块中),您需要使用带连字符的语法(即p <<-END_SQL
而不是{ {1}})。否则,缩进空格会使标识符被解释为字符串的延续。
这不会节省太多打字,但它看起来比使用+标志更好。
编辑:再添加一个:
p <<END_SQL
答案 1 :(得分:162)
是的,如果您不介意插入额外的换行符:
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
答案 2 :(得分:158)
在ruby 2.0中,您现在可以使用%
例如:
SQL = %{
SELECT user, name
FROM users
WHERE users.id = #{var}
LIMIT #{var2}
}
答案 3 :(得分:51)
您已经阅读过多行字符串的多种语法。我最喜欢的是Perl风格:
conn.exec %q{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}
多行字符串以%q开头,后跟一个{,[或(然后由相应的反转字符终止。%q不允许插值;%Q这样做可以写出这样的内容:< / p>
conn.exec %Q{select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from #{table_names},
where etc etc etc etc etc etc etc etc etc etc etc etc etc}
我实际上不知道如何调用这些多行字符串,所以让我们称它们为Perl多线。
但是请注意,无论你使用Perl多线还是像Mark和Peter所建议的那样,你最终都会得到可能不必要的空格。在我的示例和它们的示例中,“from”和“where”行包含前导空格,因为它们在代码中缩进。如果不需要这个空格,那么你必须像现在一样使用连接字符串。
答案 4 :(得分:29)
有时值得删除新的字符\n
,如:
conn.exec <<-eos.squish
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
答案 5 :(得分:17)
您也可以使用双引号
x = """
this is
a multiline
string
"""
2.3.3 :012 > x
=> "\nthis is\na multiline\nstring\n"
如果需要删除换行符&#34; \ n&#34;使用反斜杠&#34; \&#34;在每一行的末尾
答案 6 :(得分:16)
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
答案 7 :(得分:11)
其他选择:
#multi line string
multiline_string = <<EOM
This is a very long string
that contains interpolation
like #{4 + 5} \n\n
EOM
puts multiline_string
#another option for multiline string
message = <<-EOF
asdfasdfsador #{2+2} this month.
asdfadsfasdfadsfad.
EOF
puts message
答案 8 :(得分:10)
最近,随着Ruby 2.3中的新功能,新的squiggly HEREDOC
将允许您以一种很好的方式编写我们的多行字符串,并且只需要进行最小的更改,因此使用此结合.squish
将允许您编写多行一个不错的方式!
[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
答案 9 :(得分:8)
从Ruby 2.3开始的Ruby-way(TM):使用 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
# -> "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,引号和字符串文字百分比均会导致换行),则可以通过在反斜杠{{1}处使用行连续 }作为一行中的最后一个非空白字符。这将继续执行该行,并使Ruby将Strings背对背连接(注意引号字符串内的空格):
\
如果您使用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'
# -> "select...from...where..."
更多详细信息:
这里的字符串字符串文档表示法是一种在代码中内联指定长文本块的方法。它以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..."
开头,后跟用户定义的字符串(字符串终止符)。连接以下所有行,直到在行的非常开始处找到“字符串结尾”终止符为止:
<<
“字符串结尾”终止符可以自由选择,但是通常使用“ EOS”(字符串结尾)之类的东西或与字符串的域匹配的东西,例如“ SQL”。
默认情况下或在EOS终止符被双引号的情况下,HEREDOC支持interpolation:
puts <<HEREDOC
Text Text Text Text
Bla Bla
HEREDOC
# -> "Text Text Text Text\nBlaBla"
如果EOS终止符用单引号引起来,则可以禁用插值:
price = 10
print <<"EOS" # comments can be put here
1.) The price is #{price}.
EOS
# -> "1.) The price is 10."
print <<'EOS' # Disabled interpolation
3.) The price is #{price}.
EOS
# -> "3.) The price is #{price}."
的一个重要限制是字符串结束符必须位于行的开头:
<<HEREDOC
为解决此问题,创建了 puts <<EOS
def foo
print "foo"
end
EOS
EOS
#-> "....def foo\n......print "foo"\n....end\n..EOS
语法。它允许缩进EOS终结符以使代码看起来更好。 <<-
和EOS终止符之间的行仍被完整使用,包括所有缩进:
<<-
从Ruby 2.3开始,我们现在有了波浪状的HEREDOC puts <<-EOS # Use <<- to indent End of String terminator
def foo
print "foo"
end
EOS
# -> "..def foo\n....print "foo"\n..end"
删除了领先的空白:
<<~
空行和仅包含制表符和空格的行将被<<〜
忽略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"
如果同时使用制表符和空格,则制表符被视为等于8个空格。 如果最小缩进线在选项卡的中间,则不会删除该选项卡。
puts <<~EOS.inspect
Hello
World!
EOS
#-> "Hello\n..World!"
HEREDOC可以做一些疯狂的事情,例如使用反引号执行命令:
puts <<~EOS.inspect
<tab>One Tab
<space><space>Two Spaces
EOS
# -> "\tOne Tab\nTwoSpaces"
HEREDOC字符串定义可以“堆叠”,这意味着第一个EOS终止符(下面的EOSFOO)将结束第一个字符串并开始第二个字符串(下面的EOSBAR):
puts <<`EOC`
echo #{price}
echo #{price * 2}
EOC
我认为没有人会这样使用它,但是print <<EOSFOO, <<EOSBAR # you can stack them
I said foo.
EOSFOO
I said bar.
EOSBAR
实际上只是一个字符串文字,可以放在通常可以放置字符串的地方:
<<EOS
如果您没有Ruby 2.3,但没有Rails 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
3.0,则可以使用与>=
相同的String.strip_heredoc
<<~
如果在Ruby解析文件时看到错误,则很可能是您的HEREDOC带有多余的前导或尾随空格,或者是波浪形的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
露比告诉你的事情
database_yml = <<~EOS
production:
database: #{fetch(:user)}
adapter: postgresql
pool: 5
timeout: 5000
EOS
出了什么问题:
在终止的EOS之后发现多余的空格。
有关如何使用百分号和括号对中的字符串(例如SyntaxError: .../sample.rb:xx: can't find string "EOS" anywhere before EOF
...sample.rb:xx: syntax error, unexpected end-of-input, expecting `end'
,%(...)
,%[...]
等或一对),请参见RubyDoc任何非字母数字字符,例如%{...}
最后,要获得对原始问题“是否有一种暗示串联的方法?”的答案。 回答:如果找到两个背对背的字符串(单引号和双引号),Ruby总是暗示连接:
%+...+
需要注意的是,这不能跨换行,因为Ruby解释的是语句的结尾,因此仅一行的字符串所产生的结果行什么也没做。
答案 10 :(得分:7)
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'
&LT;&LT;是字符串的连接运算符
答案 11 :(得分:5)
如果您 介意额外的空格和换行符,则可以使用
conn.exec %w{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} * ' '
(对插值字符串使用%W)
答案 12 :(得分:3)
conn.exec [
"select attr1, attr2, attr3, ...",
"from table1, table2, table3, ...",
"where ..."
].join(' ')
这个建议比here-documents和long字符串更有优势,自动压缩器可以适当地缩进字符串的每个部分。但它带来了效率成本。
答案 13 :(得分:3)
为避免关闭每一行的括号,您只需使用带反斜杠的双引号来转义换行符:
"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"
答案 14 :(得分:1)
<<~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
有所不同,前者保留了块内的间距,而后者则没有。
还有其他选择。 像串联等,但是从总体上讲,这更有意义。
如果我在这里错了,请让我知道...
答案 15 :(得分:1)
和您一样,我也在寻找一个不包含换行符的解决方案。 (尽管它们在SQL中可能是安全的,但就我而言,它们并不安全,并且我要处理大量文本)
这可以说是丑陋的,但是您可以在Heredoc中反斜杠转义换行以从结果字符串中省略它们:
conn.exec <<~END_OF_INPUT
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
END_OF_INPUT
请注意,如果没有插值(即<<~'END_OF_INPUT'
),您将无法做到这一点,因此请小心。 #{expressions}
将在此处进行评估,而不会在您的原始代码中进行评估。因此,A. Wilson's answer可能更好。