Chr*_*ier 83 ruby whitespace heredoc
我正在尝试制作一个Ruby heredoc的问题.它正在返回每行的前导空格,即使我包含 - 运算符,它应该抑制所有前导空白字符.我的方法看起来像这样:
def distinct_count
<<-EOF
\tSELECT
\t CAST('#{name}' AS VARCHAR(30)) as COLUMN_NAME
\t,COUNT(DISTINCT #{name}) AS DISTINCT_COUNT
\tFROM #{table.call}
EOF
end
Run Code Online (Sandbox Code Playgroud)
我的输出如下:
=> " \tSELECT\n \t CAST('SRC_ACCT_NUM' AS VARCHAR(30)) as
COLUMN_NAME\n \t,COUNT(DISTINCT SRC_ACCT_NUM) AS DISTINCT_COUNT\n
\tFROM UD461.MGMT_REPORT_HNB\n"
Run Code Online (Sandbox Code Playgroud)
当然,这在这个特定的例子中是正确的,除了第一个"和\ t之间的所有空格.有没有人知道我在这里做错了什么?
Phi*_*oss 131
<<-
heredoc 的形式只忽略末尾分隔符的前导空格.
使用Ruby 2.3及更高版本,您可以使用波浪形的heredoc(<<~
)来抑制内容行的前导空格:
def test
<<~END
First content line.
Two spaces here.
No space here.
END
end
test
# => "First content line.\n Two spaces here.\nNo space here.\n"
Run Code Online (Sandbox Code Playgroud)
从Ruby 文字文档:
最小缩进行的缩进将从内容的每一行中删除.请注意,为了确定缩进,将忽略仅由文字制表符和空格组成的空行和行,但转义制表符和空格被视为非缩进字符.
chr*_*isk 122
如果您使用的是Rails 3.0或更高版本,请尝试#strip_heredoc
.文档中的这个示例打印前三行没有缩进,同时保留最后两行的两个空格缩进:
if options[:usage]
puts <<-USAGE.strip_heredoc
This command does such and such.
Supported options are:
-h This message
...
USAGE
end
Run Code Online (Sandbox Code Playgroud)
该文件还指出:"从技术上讲,它看起来整个字符串中的至少缩进线,并删除前导空格的量."
这是active_support/core_ext/string/strip.rb的实现:
class String
def strip_heredoc
indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
gsub(/^[ \t]{#{indent}}/, '')
end
end
Run Code Online (Sandbox Code Playgroud)
您可以在test/core_ext/string_ext_test.rb中找到测试.
ein*_*nus 44
没什么可做的,我知道我害怕.我经常这样做:
def distinct_count
<<-EOF.gsub /^\s+/, ""
\tSELECT
\t CAST('#{name}' AS VARCHAR(30)) as COLUMN_NAME
\t,COUNT(DISTINCT #{name}) AS DISTINCT_COUNT
\tFROM #{table.call}
EOF
end
Run Code Online (Sandbox Code Playgroud)
这有效,但有点黑客.
编辑:从下面的Rene Saarsoo获取灵感,我建议这样的事情:
class String
def unindent
gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "")
end
end
def distinct_count
<<-EOF.unindent
\tSELECT
\t CAST('#{name}' AS VARCHAR(30)) as COLUMN_NAME
\t,COUNT(DISTINCT #{name}) AS DISTINCT_COUNT
\tFROM #{table.call}
EOF
end
Run Code Online (Sandbox Code Playgroud)
这个版本应该处理第一行不是最左边的那一行.
Phr*_*ogz 22
这是我使用的一个更简单的unindent脚本版本:
class String
# Strip leading whitespace from each line that is the same as the
# amount of whitespace on the first line of the string.
# Leaves _additional_ indentation on later lines intact.
def unindent
gsub /^#{self[/\A[ \t]*/]}/, ''
end
end
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
foo = {
bar: <<-ENDBAR.unindent
My multiline
and indented
content here
Yay!
ENDBAR
}
#=> {:bar=>"My multiline\n and indented\n content here\nYay!"}
Run Code Online (Sandbox Code Playgroud)
如果第一行可能比其他行缩进更多,并希望(如Rails)基于最小缩进行而取消,您可能希望使用:
class String
# Strip leading whitespace from each line that is the same as the
# amount of whitespace on the least-indented line of the string.
def strip_indent
if mindent=scan(/^[ \t]+/).min_by(&:length)
gsub /^#{mindent}/, ''
end
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,如果您扫描\s+
而不是[ \t]+
您,最终可能会从您的heredoc中删除换行符而不是前导空格.不可取!
<<-
在Ruby中只会忽略结束分隔符的前导空格,允许它正确缩进.尽管网上有些文档可能会说,但它并没有删除字符串内部行的前导空格.
您可以使用gsub
以下方法自行删除前导空格:
<<-EOF.gsub /^\s*/, ''
\tSELECT
\t CAST('#{name}' AS VARCHAR(30)) as COLUMN_NAME
\t,COUNT(DISTINCT #{name}) AS DISTINCT_COUNT
\tFROM #{table.call}
EOF
Run Code Online (Sandbox Code Playgroud)
或者,如果您只想删除空格,请留下标签:
<<-EOF.gsub /^ */, ''
\tSELECT
\t CAST('#{name}' AS VARCHAR(30)) as COLUMN_NAME
\t,COUNT(DISTINCT #{name}) AS DISTINCT_COUNT
\tFROM #{table.call}
EOF
Run Code Online (Sandbox Code Playgroud)
一些其他答案找到最小缩进行的缩进级别,并从所有行中删除它,但考虑到编程中缩进的性质(第一行是最少缩进的),我认为你应该寻找缩进级别的第一行.
class String
def unindent; gsub(/^#{match(/^\s+/)}/, "") end
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
28667 次 |
最近记录: |