我正在使用rake脚本来标记我的.NET项目中的AssemblyInfo.cs文件,但是引入了一个幻像回车(或换行符等),它正在打破编译。获取版本号的方法是:
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.>")
答案 0 :(得分:1)
Readlines不会隐含地从行尾删除换行符。通常人们会选择chomp!在结果上。您可以使用p方法(或调试器,我猜)计算这样的事情,在调用gsub之前添加p line
。然后你应该看到(除非我非常错误)您的版本实际上看起来像"64:67M\n"
但是,您有一个更简单的解决方案,String#to_i
会将字符串转换为int,直到找到非数字。所以"64:67M".to_i # => 64
和"64:67M\n".to_i # => 64
这使您无需成为正则表达式忍者,并解决了换行问题。
答案 1 :(得分:1)
这并没有真正解决你的问题,这里有一点重构第二种方法,使它看起来更像是惯用的红宝石。我知道我在学习语言时用同样的方式编写了它,但是有很多东西使得这个函数看起来像C#或用ruby编写的java。
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代码中涉及很多个人风格,这就是我的方式。在我学习的时候,这种事情对我来说是纯金,所以我将逐步详细说明为什么我改变了我所改变的东西。
所以,从顶部开始:)
首先,我从方法签名中删除了parens。作为一般惯例,除非你需要,否则你不应该使用parens,因为过多的标点符号往往会使内容难以阅读。同样从file_path转到路径,这只是一个简洁的事情(和个人品味)
接下来,您永远不会在ruby中看到if not
,始终使用unless
。需要一点时间来习惯,但读取时需要做的布尔代数越少越好。删除了一些parens(与第一次相同的推理),并将||
切换为or
。
说到and/or
vs &&/||
,我更喜欢前者(回到标点符号)。话虽如此,由于运算符优先级的不同,使用该表单可能会发生相当大的问题。假设你有类似的东西
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
。
正如您所看到的,这可能导致真正奇怪的错误。因此,很多rubyists只使用&amp;&amp; / ||完全形成。就个人而言,我只是试着记住这个问题,因为我真的喜欢和/或更好。
在guard子句的最后一点,我交换了%{...}
语法的引号。有一种绝对疯狂的方法可以在ruby中创建字符串文字。因此,总有办法避免不得不逃避你的报价。
接下来的改变只是简洁的名义。一般来说,我尽量减少我使用的变量,尽管这也是一种风格。
下一次变化是最大的。
我做的第一件事就是改变你所有的正则表达式,在我们希望保持不变的开始和结束位置周围进行分组(()
),并删除我们想要改变的东西的分组。我这样做是因为使用gsub,我们可以获得对另一方的组匹配的引用(\1
是第一组,\2
第二组)。在减少噪音方面,这有很大帮助,正则表达已经足够难以阅读; - )
接下来,我试图解决你基本上是以蛮力的方式将相同的操作应用于四件事。当你发现自己这样做时,如果你将操作与想要操作的操作分开,通常会使事情变得更加清晰。这里的另一个考虑因素是我们正在处理适度长的正则表达式,这些正则表达式本身很难全部阅读。
将这些内容放入正则表达式的哈希值中,并将其替换为更清晰的内容。所以现在我们可以遍历那个哈希并进行替换。
您可能会注意到我已将gsub
更改为gsub!
,并取消了作业。一般而言,以!
结尾的方法将是不以!
结尾的方法的变体,但在某种程度上您必须更加注意使用它。在这种情况下,gsub
返回带有替换的新字符串,gsub!
进行替换。这里的另一点是,在ruby中,字符串是可变的,这是与C#的细微差别,但允许像现场替换这样的事情。
一般来说,大多数差异可归结为三件事; DRY(不要重复自己)在ruby中进一步使用它然后它在C#中,除非你需要,否则不要使用标点符号,并且通过尽可能少打字(在降低可读性之前)来处理语言的简洁性< / p>
如果您有任何意见/问题,请告诉我,祝您在进一步的红宝石冒险中好运:)