如何从Ruby Heredoc中删除前导空格,同时保留2个前导空格

时间:2012-07-15 15:01:34

标签: ruby whitespace heredoc thor

How do I remove leading whitespace chars from Ruby HEREDOC?

部分回答了这个问题

在Rails 3中,有一个方法#strip_heredoc,它会删除所有空格。 但是当在已经具有标识的现有文件中插入行时,这不能很好地工作。一个例子:

begin
  insert_into_file "#{app_name}/config/environments/production.rb", <<-DEVISE_MAILER_STUFF.strip_heredoc, :before => "end\n"
    # for devise
    config.action_mailer.default_url_options = { :protocol => 'https', :host => 'YOURHOSTNAME' }
    config.action_mailer.delivery_method = :smtp
    something.each do |x|
      do stuff
    end
  DEVISE_MAILER_STUFF
end

仅添加'begin'和'end'以显示源代码具有缩进。 heredoc在'#for devise'之前有4个空格。 @strip_heredoc将删除所有这些空格,但它会在“do stuff”行中保留两个额外的空格。

environments/production.rb中,这将是这样的:

MyApp::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb
  # *** Identation here is two spaces! (We are in a block.) ***

# for devise
config.action_mailer.default_url_options = { :protocol => 'https', :host => 'YOURHOSTNAME' }
config.action_mailer.delivery_method = :smtp
something.each do |x|
  do stuff
end

  # back to original identation of this file
end # MyApp::Application.configure block!

如何解决这个问题? 也许有其他方式而不是heredoc? 我想也许strip_heredoc(min)其中min是要保留的空格的最小值,但我认为这不适用于标签。或者让heredoc的第一行确定左边距,如下所示:

puts <<-HEREDOC
  FIRST_LINE
    Real code here
HEREDOC

'{1}}将删除'FIRST_LINE',但它也会设置需要删除的空格/空格数。所以输出在'Real code here'前面有两个空格。

更新:可能是这样的:

strip_heredoc

3 个答案:

答案 0 :(得分:2)

我按照here描述strip_heredoc_with_indent(indent)

答案 1 :(得分:0)

自己脱掉它。

insert_into_file "#{app_name}/config/environments/production.rb",
                 <<-DEVISE_MAILER_STUFF.gsub(/^  /, ''), :before => "end\n"
  ...
DEVISE_MAILER_STUFF

这表示在每行的开头,用空字符串替换两个空格。它很简单,易于理解,易于修复或更改。


或者,您可以在模板中执行此操作,但我无法判断您是否实际使用模板,或者您是否以某种方式解析文件并替换行(提示,您应该使用的是模板)。


“我想也许是strip_heredoc(min),其中min是要保留的空间的最小值,但是我认为这不适用于标签。”

Ruby标准是两个空格。即使不是这样,标签也总是搞砸了。使用空格。


关于您的更新

这很复杂。你需要像这样的通用解决方案吗?你在很多地方这样做吗?或者在你不能只看一眼并看到gsub多少的地方?此外,扩展核心类是一个危险的游戏,我已经看到了Rails 1和自定义Ruby 1.8的代码库,因为他们对改变内置行为太过苛刻了。当它发生变化时,它们无法随之改变。我知道Rails会这样做,但Rails不是最佳实践的好参考。

它也有一些潜在的错误:

  • 当给出这个String并且没有传递params时,它应该怎么做? “a \ n \ n b”我不指望什么,因为最短的一行是空行,所以你的new_indent应该是零,但它将是一个。
  • 当他们传入的缩进超过scan(...).min.size
  • 时会发生什么
  • 如果他们传递了消极的东西会怎样?

对我而言,它最终似乎是一个复杂的解决方案,它无法真正正确,它将使用它的任何代码耦合到这个应用程序,而所有这些可能实际上并不是必需的。

答案 2 :(得分:0)

您可以使用某种分隔符来指示左边距。

def heredoc_with_margin()
  doc = <<-EOT.gsub(/^\s*\|/, '')
    |top:
    |  sub-one:
    |    sub-sub-one
    |  sub-two:
    |    sub-sub-two
    EOT
  return doc
end