010.Heredoc trong Ruby.


Giai đoạn đầu coding với Ruby, nếu mentor của bạn có tâm, hẳn là bạn sẽ có một bài tập kiểu như tạo một file mới, mở file đó ra, chèn text vào file đó. Rồi bạn gặp rắc rối với những đoạn văn bản dài khi xuống dòng.
Hoặc là những khi bạn query SQL thuần, những câu query dài cả chục dòng làm chính bạn cũng tự phải hoa cả mắt, mặc dù đã dễ dãi với bản thân lắm rồi.
Đây chính là lúc dùng Heredoc! Ừ, để cho đẹp code, dễ đọc hơn vậy thôi!
Input text sample
def hello
puts <<-EOS
Hello,
World!
EOS
end
hello
# Hello,
# World!
Như bạn thấy, Hello và Word không bị dính chung trên một dòng, mặc dù chả có \n ở đây
Ơ nhưng mà Hello với World bị dính space ở đầu, vì chúng ta canh chỉnh dòng theo syntax Ruby. Để loại bỏ điều này, từ phiên bản Ruby 2.3, chúng ta có thể sử dụng «~ thay cho «-
def hello
puts <<~EOS
Hello,
World!
EOS
end
hello
#Hello,
#World!
Heredoc in SQL query
query = "SELECT * FROM foods where healthy = true"
result = ActiveRecord::Base.connection.execute(query)
query = <<-SQL
SELECT * FROM foods
WHERE healthy = true
SQL
result = ActiveRecord::Base.connection.execute(query)
So sánh 2 syntax trên, dùng heredoc nhìn có vẻ thuận tự nhiên hơn, thậm chí code SQL của bạn còn được highlight nữa.
Giờ hãy thử chèn thêm một số biến Ruby vào nào, ở đời làm gì có chuyện query tĩnh thế này T_T
type = "healthy"
table = "foods"
query = <<-SQL
SELECT * FROM #{table}
WHERE #{type} = true
SQL
result = ActiveRecord::Base.connection.execute(query)
Hoặc có thể dùng với find_by_sql thế này nữa, vô tư luôn
rating = 3.0
Post.find_by_sql(<<~SQL)
SELECT p.title, c.author
FROM posts p, comments c
WHERE p.id = c.post_id AND p.rating > #{rating}
SQL
Heredoc in somewhere else
À mém quên vụ edit file, code đây các bro
File.open('test.txt', 'w') do |f|
f << <<-HEREDOC
This is line one
This is line two
This file is edited on #{Time.zone.now}
HEREDOC
end
Bỏ HEREDOC vào nháy đơn sẽ khiến văn bản không nhận biến Ruby nữa
File.open('test.txt', 'w') do |f|
f << <<-'HEREDOC'
This is line one
This is line two
This file is edited on #{Time.zone.now}
HEREDOC
end
Hoặc có thể sử dụng heredoc cho bash script cũng được luôn
> str = <<~`HEREDOC`
date
HEREDOC
=> "Wed Mar 25 18:51:08 IST 2020\n"
Comments