Откуда эта новая строка? - PullRequest
0 голосов
/ 02 июля 2010

Я использую скрипт rake для пометки файлов AssemblyInfo.cs в моих проектах .NET, но вводится возврат каретки (или перевод строки и т. Д.), Который нарушает компиляцию. Метод, который получает номер версии:

def get_version()
  version = ''
  IO.popen("#{SVNVERSION_APPLICATION} #{build_info.root_dir}") do |output|
    output.readlines.each do |line|
      version << line.gsub(/\:.*/, '')
    end
  end
  result = version
end

Если есть лучший способ сделать это, пожалуйста, дайте мне знать. Я в основном возился здесь (и это на самом деле первый Ruby, над которым я когда-либо работал, так что терпите меня). Как вы можете видеть (а мои навыки регулярных выражений никогда не были на уровне ниндзя), я просто пытаюсь избавиться от первого двоеточия и всего после него. Svnversion возвращает такие вещи, как "64:67M", и меня интересует только первое число.

Затем я помечаю файлы так:

contents = contents.gsub(/AssemblyVersion\(\"([\d.*]*)\"\)/, "AssemblyVersion(\"#{helper.build_info.build_number_template}\")")

Естественно, есть больше кода, окружающего эти биты. Это просто мясо того, что происходит. По сути, в задаче я вызываю get_version для сохранения номера версии на вспомогательном объекте, и этот объект позже используется в методе, который считывает файлы AssemblyInfo.cs в «содержимое», выполняет подстановку и записывает ее обратно.

Все работает нормально, за исключением фантомного перевода строки в выводе:

[assembly: AssemblyVersion("1.1.0.62
")]
[assembly: AssemblyFileVersion("1.1.0.62
")]

Я попытался добавить еще один .gsub, чтобы попытаться отфильтровать \ n и \ r, но безуспешно, я попробовал .chomp и т. Д. Всегда кажется, что эта новая строка помещается в получившийся файл.

Я что-то упускаю из виду?

[Изменить в ответ на первый ответ:]

Вот метод, который редактирует файл AssemblyInfo.cs:

def replace_assembly_strings(file_path, helper)

    if not (File.exists?(file_path) || File.writable?(file_path))
      raise "the file_path \"#{file_path}\" can not be written to.  Does it exist?"
    end

    path = Pathname.new(file_path)
    contents = path.read
    puts "AssemblyVersion(\"#{helper.build_info.build_number_template}\")"
    contents = contents.gsub(/AssemblyVersion\(\"([\d.*]*)\"\)/, "AssemblyVersion(\"#{helper.build_info.build_number_template}\")")
    contents = contents.gsub(/AssemblyFileVersion\(\"([\d.*]*)\"\)/, "AssemblyFileVersion(\"#{helper.build_info.build_number_template}\")")
    contents = contents.gsub(/AssemblyCompany\(\"(.*)\"\)/, "AssemblyCompany(\"#{helper.build_info.company}\")")
    contents = contents.gsub(/AssemblyCopyright\(\"(.*)\"\)/, "AssemblyCopyright(\"#{helper.build_info.copyright}\")")

    File.open(file_path, 'w') {|f| f.write(contents)}

  end

Это puts строка выводит AssemblyVersion("1.1.0.62"), но в результате файл показывает AssemblyVersion("1.1.0.>")

Ответы [ 2 ]

1 голос
/ 03 июля 2010

Это на самом деле не решает вашу проблему, вот небольшой рефакторинг этого второго метода, чтобы он выглядел немного более похожим на идиоматический рубин.Я знаю, что писал так же, когда изучал язык, но было много вещей, которые делали эту функцию похожей на C # или java, написанную на ruby.

def replace_assembly_strings path, helper
  raise %{the path "#{path}" can not be written to.  Does it exist?} unless File.exists?(path) or File.writable?(path)

  file = Pathname.new(path).read

  methods = {/(AssemblyVersion\(\")[\d.*]*(\"\))/      => helper.build_info.build_number_template, 
             /(AssemblyFileVersion\(\")[\d.*]*(\"\))/  => helper.build_info.build_number_template, 
             /(AssemblyCopyright\(\").*(\"\))/         => helper.build_info.copyright,
             /(AssemblyCompany\(\").*(\"\))/           => helper.build_info.company}

  methods.keys.each do |regex| 
    file.gsub! regex, "\1#{methods[regex]}\2"
  end

  File.open(path, 'w') {|f| f.write(file)}
end

Есть много личногостиль, включенный в код ruby, это то, как я бы это сделал.Подобные вещи были для меня чистым золотом, когда я учился, поэтому я подробно расскажу, почему я изменил то, что изменил.

Итак, начиная сверху:)

Сначала я убрал парены из подписи метода.Как правило, вы не должны использовать парены, если в этом нет необходимости, так как чрезмерная пунктуация делает материал труднее для чтения.Также прошел путь от file_path к path, опять же, это просто краткость (и личный вкус)

Далее, вы никогда не увидите if not в ruby, unless всегда используется.Требуется немного привыкнуть, но чем меньше логической алгебры вам нужно делать во время чтения, тем лучше.Также убрал несколько паренов (те же рассуждения, что и в первый раз) и переключил || на or.

Когда дело доходит до and/or против &&/||, мне немного больше нравится первое.больше (возвращаясь к пункту пунктуации).При этом из-за различий в приоритетах операторов может возникнуть довольно много проблем.Допустим, у вас есть что-то вроде этого

def foo bar
  'foobar!' if bar
end

foobar = foo false || true
# foobar == 'foobar!'

Сначала произойдет false || true оценка до true, затем true будет переведено в foo.если мы пойдем другим путем

foobar = foo false or true
# foobar == true ????

первым, false будет передано foo.foo вернет nil, а nil считается false в логических выражениях, поэтому nil or true в итоге оценивается как true.

Как видите, это может привести к ДЕЙСТВИТЕЛЬНОстранные ошибкиИз-за этого многие рубинисты просто используют && / ||формы исключительно.Лично я просто пытаюсь запомнить эту проблему, потому что мне действительно нравится и / или лучше.

В последнем пункте предложения охраны я поменял местами цитаты для %{...} синтаксиса.Существует множество безумных способов сделать строковые литералы в ruby.Из-за этого всегда есть способ избежать необходимости избегать ваших цитат.

Следующее изменение было только во имя краткости.В общем, я стараюсь минимизировать количество переменных, которые я использую, хотя это тоже стиль.

Следующее изменение - самое большое.

Первым делом я изменил все ваши регулярные выражения, чтобы они имели группировку (()) вокруг начального и конечного битов, которые мы хотели оставить прежними, и удалили группировку вокруг того, что мы хотим изменить.Я сделал это, потому что с помощью gsub мы можем получить ссылку на то, что было сопоставлено группами на другой стороне (\1 - первая группа, \2 - вторая).Это очень помогает, когда дело доходит до уменьшения шума, регулярные выражения уже достаточно сложны для чтения; -)

Далее я попытался сказать, что вы в основном применяли одну и ту же операцию к четырем вещам в грубой форме.путь.Когда вы обнаруживаете, что делаете это, обычно становится намного яснее, если вы отделяете операцию от того, над чем хотите работать.Другое соображение здесь заключается в том, что мы имеем дело с умеренно длинными регулярными выражениями, которые, опять же, достаточно сложны для самостоятельного чтения.

Извлечение этого материала в хеш регулярного выражения и его замена делает этонамного понятнее.Так что теперь мы можем перебрать этот хеш и сделать замену.

Вы можете заметить, что я изменил gsub на gsub! и избавился от задания.В общем, методы, которые заканчиваются на !, будут вариантами тех, которые не заканчиваются на !, но в некотором смысле, когда вы должны уделять больше внимания его использованию.В этом случае gsub возвращает новую строку с подстановкой, gsub! выполняет подстановку на месте.Другой момент здесь заключается в том, что в ruby ​​строки являются изменяемыми, что является тонким отличием от C #, но допускает такие вещи, как замена на месте.

В целом, большинство различий можно свести к трем вещам;«СУХОЙ» (не повторяйте себя) далее идет в рубине, чем в C #, не используйте пунктуацию, если вам не нужно, и придерживайтесь краткости языка, выполняя наименьшее количество набираемого текста (до того, как уменьшится читабельность)1064 *

Дайте мне знать, если у вас есть какие-либо комментарии / вопросы, и удачи вам в дальнейших приключениях в рубине:)

1 голос
/ 02 июля 2010

Readlines неявно удаляет символ новой строки в конце строки. Обычно люди вызывают Chomp! на результат. Вы можете понять такие вещи с помощью метода p (или, я полагаю, отладчика), добавив p line перед тем, как вызывать свой gsub. Тогда вы должны увидеть (если я не поразительно ошибаюсь), что ваши версии на самом деле выглядят как "64:67M\n" Однако, у вас есть более простое доступное решение, String#to_i преобразует строку в int, пока не найдет не цифру. Так что "64:67M".to_i # => 64 и "64:67M\n".to_i # => 64 Что избавляет вас от необходимости быть регулярным ниндзя и решает проблему с новой строкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...