Ruby-way (TM) kể từ Ruby 2.3: Sử dụng HEREDOC nguệch ngoạc <<~
để xác định chuỗi nhiều dòng với dòng mới và thụt lề thích hợp:
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..."
Nếu thụt lề thích hợp không phải là một mối quan tâm, thì dấu ngoặc đơn và dấu ngoặc kép có thể trải dài trên nhiều dòng trong 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..."
Nếu trích dẫn đơn hoặc kép là cồng kềnh vì điều đó sẽ cần nhiều lối thoát, thì ký hiệu chuỗi phần trăm %
là giải pháp linh hoạt nhất:
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..."
Nếu mục đích là để tránh các dòng mới (mà cả HEREDOC nguệch ngoạc, trích dẫn và chuỗi phần trăm theo nghĩa đen sẽ gây ra), thì có thể sử dụng tiếp tục dòng bằng cách đặt dấu gạch chéo ngược \
làm ký tự không khoảng trắng cuối cùng trong một dòng. Điều này sẽ tiếp tục dòng và sẽ khiến Ruby nối chuỗi trở lại (xem ra những khoảng trống bên trong chuỗi được trích dẫn):
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..."
Nếu bạn sử dụng Rails String.squish
sẽ tách chuỗi không gian hàng đầu và dấu và thu gọn tất cả các khoảng trắng liên tiếp (dòng mới, tab và tất cả) vào một khoảng trắng:
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..."
Thêm chi tiết:
Cú pháp của Ruby HEREDOC
Ký hiệu tài liệu ở đây cho chuỗi hoạt động là một cách để chỉ định các khối văn bản dài trong mã. Nó được bắt đầu bằng <<
theo sau bởi một chuỗi do người dùng định nghĩa (bộ kết thúc chuỗi kết thúc). Tất cả các dòng sau được nối cho đến khi kết thúc chuỗi kết thúc được tìm thấy ở đầu dòng:
puts <<HEREDOC
Text Text Text Text
Bla Bla
HEREDOC
# -> "Text Text Text Text\nBlaBla"
Bộ kết thúc chuỗi kết thúc có thể được chọn tự do, nhưng thông thường sử dụng một cái gì đó như "EOS" (Kết thúc chuỗi) hoặc thứ gì đó phù hợp với miền của Chuỗi như "SQL".
HEREDOC hỗ trợ nội suy theo mặc định hoặc khi bộ kết thúc EOS được trích dẫn kép:
price = 10
print <<"EOS" # comments can be put here
1.) The price is #{price}.
EOS
# -> "1.) The price is 10."
Nội suy có thể bị vô hiệu hóa nếu bộ kết thúc EOS được trích dẫn đơn:
print <<'EOS' # Disabled interpolation
3.) The price is #{price}.
EOS
# -> "3.) The price is #{price}."
Một hạn chế quan trọng của việc <<HEREDOC
đó là bộ kết thúc Chuỗi kết thúc cần ở đầu dòng:
puts <<EOS
def foo
print "foo"
end
EOS
EOS
#-> "....def foo\n......print "foo"\n....end\n..EOS
Để giải quyết vấn đề này, <<-
cú pháp đã được tạo. Nó cho phép bộ kết thúc EOS được thụt lề để làm cho mã trông đẹp hơn. Các đường giữa bộ <<-
kết thúc và EOS vẫn được sử dụng trong phần mở rộng đầy đủ của chúng bao gồm tất cả các vết lõm:
puts <<-EOS # Use <<- to indent End of String terminator
def foo
print "foo"
end
EOS
# -> "..def foo\n....print "foo"\n..end"
Kể từ Ruby 2.3, giờ đây chúng ta có HEREDOC nguệch ngoạc <<~
loại bỏ khoảng trắng hàng đầu:
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"
Các dòng và dòng trống chỉ chứa các tab và khoảng trắng bị bỏ qua bởi << ~
puts <<~EOS.inspect
Hello
World!
EOS
#-> "Hello\n..World!"
Nếu cả tab và khoảng trắng được sử dụng, các tab được coi là bằng 8 khoảng trắng. Nếu dòng thụt lề ít nhất ở giữa một tab, tab này sẽ không bị xóa.
puts <<~EOS.inspect
<tab>One Tab
<space><space>Two Spaces
EOS
# -> "\tOne Tab\nTwoSpaces"
HEREDOC có thể thực hiện một số nội dung điên rồ như thực thi các lệnh bằng cách sử dụng backticks:
puts <<`EOC`
echo #{price}
echo #{price * 2}
EOC
Các định nghĩa Chuỗi HEREDOC có thể được "xếp chồng", điều đó có nghĩa là bộ kết thúc EOS đầu tiên (EOSFOO bên dưới) sẽ kết thúc chuỗi đầu tiên và bắt đầu chuỗi thứ hai (EOSebar bên dưới):
print <<EOSFOO, <<EOSBAR # you can stack them
I said foo.
EOSFOO
I said bar.
EOSBAR
Tôi không nghĩ có ai từng sử dụng nó như vậy, nhưng <<EOS
thực sự chỉ là một chuỗi theo nghĩa đen và có thể được đặt ở bất cứ nơi nào một chuỗi thường có thể được đặt:
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
Nếu bạn không có Ruby 2.3, nhưng Rails >=
3.0 thì bạn có thể sử dụng String.strip_heredoc
nó giống như<<~
# 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
Phần trăm chuỗi ký tự
Xem RubyDoc về cách sử dụng các dấu hiệu tỷ lệ phần trăm theo sau là một chuỗi trong một cặp ngoặc đơn như một %(...)
, %[...]
,%{...}
, vv hoặc một cặp bất kỳ ký tự chữ và số không như%+...+
Những từ cuối
Cuối cùng, để có được câu trả lời cho câu hỏi ban đầu "Có cách nào để ám chỉ sự kết hợp không?" đã trả lời: Ruby luôn ngụ ý nối nếu hai chuỗi (trích dẫn đơn và kép) được tìm thấy trở lại:
puts "select..." 'from table...' "where..."
# -> "select...from table...where..."
Thông báo trước là điều này không hoạt động trên các ngắt dòng, bởi vì Ruby đang diễn giải một kết thúc của câu lệnh và dòng kết quả của chỉ một chuỗi trên một dòng không làm gì cả.