1

この質問は、Ruby HEREDOC から先頭の空白文字を削除するにはどうすればよいですか?で部分的に回答されています。

Rails 3 には、#strip_heredocすべての空白を削除する というメソッドがあります。しかし、既に ID を持つ既存のファイルに行を挿入する場合、これはうまく機能しません。例:

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」は、ソース コードにインデントがあることを示すためにのみ追加されています。ヒアドキュメントには、「# for devise」の行の前に 4 つのスペースがあります。@strip_heredoc はこれらのスペースをすべて削除しますが、「do stuff」行の 2 つの余分なスペースは維持します。

これ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!

これを解決するには?ヒアドキュメントの代わりに他の方法があるのではないでしょうか? strip_heredoc(min)最小限のスペースはどこにあるのだろうかと思っminたのですが、それはタブではうまく機能しないと思います。または、次のように、ヒアドキュメントの最初の行で左マージンを決定します。

puts <<-HEREDOC
  FIRST_LINE
    Real code here
HEREDOC

その「FIRST_LINE」はによって削除されstrip_heredocますが、削除する必要があるスペース/空白の数も設定されます。したがって、出力には「Real code here」の前に 2 つのスペースが含まれます。

更新:おそらく次のようなもの:

String.class_eval do
  def strip_heredoc_with_indent(indent=0)
    new_indent = ( self.empty? ? 0 : ( scan(/^[ \t]*(?=\S)/).min.size - indent ) )
    gsub(/^[ \t]{#{new_indent}}/, '')
  end
end
4

3 に答える 3

2

ここでstrip_heredoc_with_indent(indent)説明したように行きました。

于 2012-07-16T23:48:18.970 に答える
0

自分で剥がします。

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

これは、各行の先頭で、2 つのスペースを空の文字列に置き換えることを示しています。シンプルで理解しやすく、修正や変更も簡単です。


または、テンプレートで行うこともできますが、実際にテンプレートを使用しているのか、何らかの方法でファイルを解析して行を置き換えているのかはわかりません (ヒント、おそらくテンプレートを使用する必要があります)。


「たぶん、strip_heredoc(min) のように考えました。min は保持するスペースの最小値ですが、タブではうまく機能しないと思います。」

Ruby の標準は 2 つのスペースです。そうでない場合でも、タブは常にすべてを台無しにします。スペースを使用します。


アップデートについて

それは複雑です。このような一般化されたソリューションが必要ですか? 色んな所でやってんの?または、一目見ただけで gsub の量を確認できない場所では? また、コア クラスの拡張は危険なゲームです。Rails 1 に固執し、Ruby 1.8 をカスタマイズしたコードベースを見てきました。それが変わったとき、彼らはそれで変わることができませんでした。Rails がそれを行うことは知っていますが、Rails はベスト プラクティスの参考にはなりません。

また、潜在的なバグがいくつかあります。

  • この文字列が与えられ、パラメータを渡さない場合、どうすればよいでしょうか? " a\n\n b" 最短の行は空の行なので、何も期待できません。したがって、new_indent は 0 である必要がありますが、1 になります。
  • それらが渡すインデントが を超えるとどうなりscan(...).min.sizeますか?
  • 彼らが否定的なものを渡すとどうなりますか?

私には、最終的には、それを使用するコードをこのアプリに結合する、真に正しいとは言えない複雑なソリューションのように思えますが、実際にはこれらすべてが必要なわけではありません.

于 2012-07-15T18:27:45.417 に答える
0

左マージンを示すために、ある種の区切り記号を使用できます。

def heredoc_with_margin()
  doc = <<-EOT.gsub(/^\s*\|/, '')
    |top:
    |  sub-one:
    |    sub-sub-one
    |  sub-two:
    |    sub-sub-two
    EOT
  return doc
end
于 2012-12-03T19:04:59.593 に答える