Is er een manier om dit er een beetje beter uit te laten zien?
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'
Zoals, is er een manier om aaneenschakeling te impliceren?
Antwoord 1, autoriteit 100%
Er zijn stukjes in dit antwoord die me hebben geholpen te krijgen wat ik nodig had (eenvoudige aaneenschakeling van meerdere regels ZONDER extra witruimte), maar aangezien geen van de daadwerkelijke antwoorden het had, compileer ik ze hier:
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"
Als bonus is hier een versie met grappige HEREDOC-syntaxis (via deze 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"
Dit laatste zou vooral voor situaties zijn die meer flexibiliteit in de verwerking vereisten. Persoonlijk vind ik het niet leuk, het zet de verwerking op een rare plek w.r.t. de string (d.w.z. ervoor, maar met gebruik van instance-methoden die meestal daarna komen), maar hij is er. Houd er rekening mee dat als u de laatste END_SQL
identifier laat inspringen (wat gebruikelijk is, aangezien dit waarschijnlijk in een functie of module zit), u de afgebroken syntaxis moet gebruiken (dat wil zeggen, p <<-END_SQL
in plaats van p <<END_SQL
). Anders zorgt de inspringende witruimte ervoor dat de identifier wordt geïnterpreteerd als een voortzetting van de string.
Dit scheelt niet veel typen, maar het ziet er voor mij leuker uit dan het gebruik van +-tekens.
Ook (ik zeg in een bewerking, enkele jaren later), als je Ruby 2.3+ gebruikt, de operator <<~ is ook beschikbaar, waardoor extra inspringing uit de laatste tekenreeks wordt verwijderd. In dat geval zou u de aanroep .gsub
moeten kunnen verwijderen (hoewel dit kan afhangen van zowel de begininspringing als uw uiteindelijke behoeften).
EDIT: Nog een toevoegen:
p %{
SELECT * FROM users
ORDER BY users.id DESC
}.gsub(/\s+/, " ").strip
# >> "SELECT * FROM users ORDER BY users.id DESC"
Antwoord 2, autoriteit 31%
In ruby 2.0 kun je nu gewoon %
. gebruiken
Bijvoorbeeld:
SQL = %{
SELECT user, name
FROM users
WHERE users.id = #{var}
LIMIT #{var2}
}
Antwoord 3, autoriteit 27%
Ja, als u het niet erg vindt dat er extra nieuwe regels worden ingevoegd:
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'
U kunt ook een 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
Antwoord 4, Autoriteit 8%
Er zijn meerdere syntaxis voor multi-line snaren zoals je al hebt gelezen. Mijn favoriet is perl-stijl:
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}
De multi-line-tekenreeks begint met% q, gevolgd door een {, [of (, en vervolgens beëindigd door het overeenkomstige omgekeerde teken.% Q staat geen interpolatie toe;% Q doet dit, zodat u dingen als deze kunt schrijven:
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}
Ik heb eigenlijk geen idee hoe deze soorten multi-line snaren worden genoemd, dus laten we ze gewoon perl multilines noemen.
Merk echter op dat of u PERL-multilines of heredocs gebruikt als Mark en Peter hebben gesuggereerd, u eindigt met mogelijk onnodige witvakken. Zowel in mijn voorbeelden als hun voorbeelden, de “van” en “waar” lijnen leidende witruimtes bevatten vanwege hun inkeping in de code. Als deze witruimte niet gewenst is, moet u aaneengeschakelde snaren gebruiken zoals u nu doet.
Antwoord 5, Autoriteit 5%
is soms de moeite waard om nieuwe lijntekens te verwijderen \n
zoals:
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
Antwoord 6, Autoriteit 4%
U kunt ook dubbele aanhalingstekens gebruiken
x = """
this is
a multiline
string
"""
2.3.3 :012 > x
=> "\nthis is\na multiline\nstring\n"
Indien nodig om de regel te verwijderen “\ n” Gebruik backslash “\” aan het einde van elke regel
Antwoord 7, Autoriteit 2%
Andere opties:
#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
Antwoord 8, Autoriteit 2%
De kronkelende HEREDOC<<~
is wat u zoekt als u een tekenreeks met meerdere regels wilt definiëren met nieuwe regels en de juiste inspringing( beschikbaar sinds Ruby 2.3):
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..."
Als de juiste inspringing geen probleem is, dan kunnen enkele en dubbele aanhalingstekensmeerdere regels in Ruby omspannen:
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..."
Als enkele of dubbele aanhalingstekens omslachtig zijn omdat er veel escapes nodig zijn, dan is de percentage letterlijke notatie%
de meest flexibele oplossing:
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..."
Als het de bedoeling is om de nieuwe regels te vermijden (die zowel de kronkelige HEREDOC, aanhalingstekens als de letterlijke procenttekenreeks zullen veroorzaken), dan kan een voortzetting van de regelworden gebruikt door een backslash \
als het laatste niet-spatieteken in een regel. Dit zet de regel voort en zorgt ervoor dat Ruby de strings rug aan rug samenvoegt (pas op voor die spaties binnen de string tussen aanhalingstekens):
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..."
Als je Rails gebruikt, String.squish
zal de reeks van voorloop- en volgspaties verwijderen en alle opeenvolgende witruimten (nieuwe regels, tabbladen en alles) samenvouwen tot één enkele spatie:
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..."
Meer details:
Ruby HEREDOC-syntaxis
De Here Document Notation for Stringsis een manier om lange blokken tekst inline in code aan te duiden. Het wordt gestart door <<
gevolgd door een door de gebruiker gedefinieerde String (de End of String-terminator). Alle volgende regels worden aaneengeschakeld totdat de End of String-terminator wordt gevonden aan het hele beginvan een regel:
puts <<HEREDOC
Text Text Text Text
Bla Bla
HEREDOC
# -> "Text Text Text Text\nBlaBla"
Het einde van de string-terminator kan vrij worden gekozen, maar het is gebruikelijk om iets als “EOS” (einde van het string) te gebruiken of iets dat overeenkomt met het domein van de string, zoals “SQL”.
Heredoc ondersteunt interpolatie Standaard of wanneer de EOS-terminator dubbel is vermeld:
price = 10
print <<"EOS" # comments can be put here
1.) The price is #{price}.
EOS
# -> "1.) The price is 10."
Interpolatie kan worden uitgeschakeld als de EOS-terminator één is vermeld:
print <<'EOS' # Disabled interpolation
3.) The price is #{price}.
EOS
# -> "3.) The price is #{price}."
Een belangrijke beperking van de <<HEREDOC
is dat het einde van het string-terminator aan het begin van de regel moet zijn:
puts <<EOS
def foo
print "foo"
end
EOS
EOS
#-> "....def foo\n......print "foo"\n....end\n..EOS"
Om dit te ronden, is de <<-
SYNTAX gemaakt. Hiermee kan de EOS-terminator ingesprongen zijn om de code er leuker uit te zien. De lijnen tussen de <<-
en EOS Terminator worden nog steeds gebruikt in hun volledige uitbreiding, inclusief alle inspringing:
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"
Sinds Ruby 2.3 hebben we nu de kronkelige HEREDOC <<~
die voorloopspaties verwijdert:
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"
Lege regels en regels die alleen tabs en spatie bevatten, worden genegeerd door <<~
puts <<~EOS.inspect
Hello
World!
EOS
#-> "Hello\n..World!"
Als zowel tabs als spaties worden gebruikt, worden tabs beschouwd als gelijk aan 8 spaties.
Als de minst ingesprongen regel zich in het midden van een tabblad bevindt, wordt dit tabblad niet verwijderd.
puts <<~EOS.inspect
<tab>One Tab
<space><space>Two Spaces
EOS
# -> "\tOne Tab\nTwoSpaces"
HEREDOC kan gekke dingen doen, zoals het uitvoeren van commando’s met backticks:
puts <<`EOC`
echo #{price}
echo #{price * 2}
EOC
HEREDOC Stringdefinities kunnen worden “gestapeld”, wat betekent dat de eerste EOS-terminator (EOSFOO hieronder) de eerste string beëindigt en de tweede start (EOSBAR hieronder):
print <<EOSFOO, <<EOSBAR # you can stack them
I said foo.
EOSFOO
I said bar.
EOSBAR
Ik denk niet dat iemand het ooit als zodanig zou gebruiken, maar de <<EOS
is eigenlijk gewoon een letterlijke tekenreeks en kan overal worden geplaatst waar een tekenreeks normaal gesproken kan worden geplaatst:
p>
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
Als je geen Ruby 2.3 hebt, maar Rails >=
3.0, dan kun je String.strip_heredoc
gebruiken, wat hetzelfde doet als <<~
# 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
Problemen oplossen
Als je fouten ziet wanneer Ruby je bestand ontleedt, dan heb je hoogstwaarschijnlijk extra voorloop- of volgspaties met een HEREDOC of extra volgspaties met een kronkelige HEREDOC. Bijvoorbeeld:
Wat je ziet:
database_yml = <<~EOS
production:
database: #{fetch(:user)}
adapter: postgresql
pool: 5
timeout: 5000
EOS
Wat Ruby je vertelt:
SyntaxError: .../sample.rb:xx: can't find string "EOS" anywhere before EOF
...sample.rb:xx: syntax error, unexpected end-of-input, expecting `end'
Wat is er fout:
Zoek de extra spaties na de beëindigende EOS.
Percentage letterlijke tekenreeksen
Zie RubyDocvoor het gebruik van het procentteken gevolgd door een tekenreeks tussen haakjes, zoals een %(...)
, %[...]
, %{...}
, enz. of een paar niet-alfanumerieke tekens zoals %+...+
Laatste woorden
Als laatste, om het antwoord te krijgen op de oorspronkelijke vraag “Is er een manier om aaneenschakeling te impliceren?”
antwoordde: Ruby impliceert altijd aaneenschakeling als twee strings (enkele en dubbele aanhalingstekens) rug aan rug worden gevonden:
puts "select..." 'from table...' "where..."
# -> "select...from table...where..."
Het voorbehoud is dat dit niet werkt over regeleinden heen, omdat Ruby een einde-instructie interpreteert en de opeenvolgende regel van alleen strings op een regel niets doet.
Antwoord 9, autoriteit 2%
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
Antwoord 10, autoriteit 2%
Onlangs met de nieuwe functies in Ruby 2.3 kun je met de nieuwe squiggly HEREDOC
onze multiline-strings op een mooie manier schrijven met een minimale verandering, dus gebruik dit in combinatie met de .squish
(als je rails gebruikt) laat je op een leuke manier multiline schrijven!
als je alleen ruby gebruikt, kun je een <<~SQL.split.join(" ")
doen, wat bijnade hetzelfde
[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"
ref: https ://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
Antwoord 11
Om te voorkomen dat de haakjes voor elke regel worden gesloten, kunt u eenvoudig dubbele aanhalingstekens met een backslash gebruiken om aan de nieuwe regel te ontsnappen:
"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"
Antwoord 12
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'
<< is de aaneenschakelingsoperator voor strings
Antwoord 13
Als u nietextra spaties en nieuwe regels vindt, kunt u gebruik maken van
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} * ' '
(gebruik% w voor geïnterpoleerde snaren)
Antwoord 14
conn.exec [
"select attr1, attr2, attr3, ...",
"from table1, table2, table3, ...",
"where ..."
].join(' ')
Deze suggestie heeft het voordeel hier-documenten en lange snaren die auto-indenters elk deel van de string op de juiste manier kunnen inspringen. Maar het komt op een efficiëntiekosten.
Antwoord 15
Elegant antwoord vandaag:
<<~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
Er is een verschil in <<-TEXT
EN <<~TEXT
, de voormalige behoudt de spatiëring in blok en laatstgenoemden niet.
Er zijn ook andere opties.
Zoals aaneenschakeling etc. Maar deze is in het algemeen logischer.
Als ik hier ongelijk heb, laat het me weten hoe …
Antwoord 16
zoals jij, ik was ook op zoek naar een oplossing die geen newlines omvat. (Hoewel ze mogelijk veilig zijn in SQL, ze zijn niet veilig in mijn geval en heb ik een groot blok tekst om mee om te gaan)
Dit is misschien wel zo lelijk, maar je kunt backslash-escape-newlines in een hereedoc backlash om ze uit de resulterende tekenreeks te laten weglopen:
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
Houd er rekening mee dat u dit niet kunt betalen zonder interpolatie (I.E. <<~'END_OF_INPUT'
), dus wees voorzichtig. #{expressions}
worden hier geëvalueerd, terwijl ze niet in je originele code staan. A. Wilsons antwoordis om die reden misschien beter.