0

特定のページのメタ タグを変更するレーキ タスクに取り組んでいます。これらのタグはコントローラーで定義されます。rake タスクは、コントローラー ファイルを開き、"@meta_tag" という語句を含む行を見つけて、replace_line(line) メソッドに従ってその行を書き直すことを目的としています。rake タスクを実行すると、エラーは発生しませんが、変更も行われません。

私の問題は「r +」行にあると思います。ファイルを 1 行で開き、別のコード行で書き込む必要がありますか?

require 'rake'
namespace :meta_tags do
  desc 'changes the meta tags'
  task :update => :environment do 

    regex = /@meta_tag/
    found = false
    file = File.open('app/controllers/site_controller.rb', 'r+')
    file.each_line do |line|
      replace_line(line) if(found)
      found = true if(line =~ regex)
    end
  end

  def replace_line(line)
    meta_tags = MetaTag.all.map { |tag| tag["tag"] }
    new_tag = meta_tags.sample(1)[0]
    line = "@meta_tag = #{new_tag}"
  end
end

私が間違っていることを見たら、私に知らせてください。

4

1 に答える 1

1

実際にはどこにもファイルに書き込みません。each_lineファイル内の各行を反復処理します (実際には、改行があるまで読み取り、この行を指定したブロックに渡します)。

しかし、インプレースfile.writeファイル書き込みは期待どおりに機能しないため、今すぐ使用するのはあまり良い考えではありません。ファイルはバイト/文字ベースであるため、置換行は古い行とまったく同じ長さでなければなりません。

したがって、通常使用される読み書きの練習を行う必要があります。また、現在のコードは発生後に行を変更します @meta_tag、あなたの質問はこれがあなたが望むものではないことを示唆しています. あなたの状況に適用される例を次に示します。

require 'rake'
namespace :meta_tags do
  desc 'changes the meta tags'
    task :update => :environment do 

    regex = /@meta_tag/
    # only 'r' since you will only read the file,
    # although you could use 'r+' and just change the lineno
    # back to 0 when finished reading...
    file = File.open('app/controllers/site_controller.rb', 'r')
    lines = []
    file.each_line do |line|
      # i don't think you need the found variable,
      # it is simple if-then/else
      (line =~ regex) ? (lines << replace_line(line)) : (lines << line)
    end
    file.close
    file = File.open('app/controllers/site_controller.rb', 'w')
    # you could also join the array beforehand,
    # and use one big write-operation,
    # i don't know which approach would be faster...
    lines.each{|line| file.write line} 
    file.close
  end

  def replace_line(line)
    meta_tags = MetaTag.all.map { |tag| tag["tag"] }
    new_tag = meta_tags.sample(1)[0]
    line = "@meta_tag = #{new_tag}\n" # added the newline
  end
end
于 2012-07-18T19:10:30.697 に答える