Ruby: Czy mogę napisać wielowierszowy ciąg bez konkatenacji?

Czy jest jakiś sposób, aby to wyglądało trochę lepiej?

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'
Na przykład, czy istnieje sposób, aby implikować konkatenację?
Author: derobert, 2010-02-25

13 answers

Są fragmenty tej odpowiedzi, które pomogły mi uzyskać to ,czego potrzebowałem( łatwa wielowierszowa konkatenacja bez dodatkowych białych znaków), ale ponieważ żadna z rzeczywistych odpowiedzi nie miała tego, kompiluję je tutaj:

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"

Jako bonus, oto wersja wykorzystująca śmieszną składnię HEREDOC (poprzez ten 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"
Ta ostatnia dotyczy głównie sytuacji, które wymagają większej elastyczności w przetwarzaniu. Osobiście nie podoba mi się to, stawia przetwarzanie w dziwnym miejscu w.R.T. ciąg (tj. przed nim, ale przy użyciu metod instancji, które zwykle pojawiają się później), ale jest tam. Zauważ, że jeśli wciąłeś ostatni identyfikator END_SQL (co jest powszechne, ponieważ prawdopodobnie znajduje się on wewnątrz funkcji lub modułu), będziesz musiał użyć składni podzielonej wyrazami (tj. p <<-END_SQL zamiast p <<END_SQL). W przeciwnym razie, wcięcia spacji powoduje, że identyfikator jest interpretowany jako kontynuacja łańcucha znaków.

To nie oszczędza dużo pisania, ale wygląda ładniej niż używanie znaków+, aby ja.

EDIT: dodanie jeszcze jednego:

p %{
SELECT * FROM     users
         ORDER BY users.id DESC
}.gsub(/\s+/, " ").strip
# >> "SELECT * FROM users ORDER BY users.id DESC"
 482
Author: A. Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-02 19:35:03

Tak, jeśli nie masz nic przeciwko dodaniu dodatkowych nowych linii:

 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'

Alternatywnie możesz użyć 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
 154
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 09:42:29

W ruby 2.0 możesz teraz po prostu użyć %

Na przykład:

SQL = %{
SELECT user, name
FROM users
WHERE users.id = #{var}
LIMIT #{var2}
}
 148
Author: Robbie Guilfoyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 01:33:51

Istnieje wiele składni dla ciągów wielowierszowych, jak już przeczytałeś. Mój ulubiony to Perl-style:

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}

Ciąg wielowierszowy rozpoczyna się od %q, po którym następuje {, [lub (, a następnie kończy się odpowiednim odwróconym znakiem. %q nie pozwala na interpolację; % Q robi, więc możesz pisać takie rzeczy:

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}

Właściwie nie mam pojęcia, jak nazywa się tego rodzaju ciągi Wielowierszowe, więc nazwijmy je po prostu wielowierszowymi Perlami.

Zauważ jednak, że czy jeśli użyjesz wielu linii Perla lub heredocs, jak zasugerowali Mark i Peter, skończysz z potencjalnie niepotrzebnymi białymi spacjami. Zarówno w moich przykładach, jak i w ich przykładach, linie "from" I "where" zawierają początkowe spacje ze względu na ich wcięcia w kodzie. Jeśli ta biała spacja nie jest pożądana, musisz użyć skonkatenowanych łańcuchów, tak jak to robisz teraz.

 51
Author: Hongli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-26 09:13:42

Czasami warto usunąć nowe znaki linii \n Jak:

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
 27
Author: Kamil Lelonek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-16 06:57:19
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
 15
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 20:51:13

Możesz również użyć trzech podwójnych cudzysłowów

x = """
this is 
a multiline
string
"""

2.3.3 :012 > x
 => "\nthis is\na multiline\nstring\n"

Jeśli potrzebne jest usunięcie podziałów linii "\n "użyj ukośnika wstecznego" \ " na końcu każdej linii

 14
Author: juliangonzalez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 23:48:05

Inne opcje:

#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
 9
Author: Alex Cohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-28 19:03:29
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'

 7
Author: Dom Brezinski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 20:52:55

Jeśli robisz pamiętaj o dodatkowych spacjach i znakach nowej linii, możesz użyć

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} * ' '

(Użyj %W dla interpolowanych łańcuchów)

 5
Author: UncleGene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-12 22:09:53

Ostatnio z nowymi funkcjami w Rubim 2.3 Nowy squiggly HEREDOC pozwoli Ci pisać nasze ciągi Wielowierszowe w miły sposób z minimalną zmianą, więc użycie tego w połączeniu z .squish pozwoli Ci pisać Wielowierszowe w miły sposób!

[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

 5
Author: Mark Jad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-01 11:42:08
conn.exec [
  "select attr1, attr2, attr3, ...",
  "from table1, table2, table3, ...",
  "where ..."
].join(' ')

Ta sugestia ma tę przewagę nad dokumentami i długimi łańcuchami, które Auto-wcięcia mogą odpowiednio wciąć każdą część łańcucha. Ale wiąże się to z kosztami wydajności.

 3
Author: Aidan Cully,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 21:10:16

Aby uniknąć zamykania nawiasów dla każdej linii, możesz po prostu użyć podwójnych cudzysłowów z odwrotnym ukośnikiem, aby uciec od nowej linii:

"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"
 2
Author: Pwnrar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-15 16:34:36