代码之家  ›  专栏  ›  技术社区  ›  David

这条新线是从哪里来的?

  •  -1
  • David  · 技术社区  · 14 年前

    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\u version将版本号存储在助手对象上,该对象稍后用于将AssemblyInfo.cs文件读入“contents”并进行替换并将其写回的方法。

    除了输出中的幻影换行符外,一切正常:

    [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 回复  |  直到 14 年前
        1
  •  1
  •   Joshua Cheek    14 年前

    Readlines不会隐式地从行尾删除换行符。通常人们都会叫它嚼!结果如何。你可以用p方法(或者调试器,我猜),加上 p line 在调用gsub之前。然后您应该看到(除非我大错特错)您的版本实际上是这样的 "64:67M\n" 但是,您有一个更简单的解决方案, String#to_i 将字符串转换为int,直到找到非数字。所以呢 "64:67M".to_i # => 64 "64:67M\n".to_i # => 64

        2
  •  1
  •   Matt Briggs    14 年前

    这并不能真正解决您的问题,下面是对第二种方法的一点重构,使其看起来更像惯用的ruby。我知道我在学习这门语言的时候也是这么写的,但是有很多东西让这个函数看起来像是用ruby编写的C或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代码中包含了很多个人风格,我就是这么做的。在我学习的时候,这种东西对我来说是纯金的,所以我会一步一步地详细讲述我为什么要改变我所改变的。

    所以,从上面开始:)

    下一步,你将永远看不到 if not unless 始终使用。这需要一点习惯,但你在阅读时需要做的布尔代数越少越好。也删除了一些paren(与第一次的推理相同),并切换了 || or .

    and/or &&/|| ,我比较喜欢前者(回到标点符号上)。也就是说,由于运算符优先级的不同,使用这种形式可能会出现很大的问题。假设你有这样的东西

    def foo bar
      'foobar!' if bar
    end
    
    foobar = foo false || true
    # foobar == 'foobar!'
    

    首先发生的是 false || true true ,那么 是的 foo

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

    第一, false . 会回来的 nil ,和 在布尔表达式中,所以 nil or true 最终评估 是的

    如你所见,这会导致非常奇怪的错误。正因为如此,许多红皮书只是使用&&/| |唯一的形式。就我个人而言,我只是试着记住这个问题,因为我真的喜欢和/或更好。

    %{...}

    下一个变化只是以简洁的名义。一般来说,我尽量减少使用的变量数量,尽管这也是一种风格。

    下一个变化是最大的。

    () )在开头和结尾部分,我们希望保持不变,并删除了围绕要更改的内容的分组。我这样做是因为有了gsub,我们可以得到另一边的组匹配的任何东西的引用( \1 \2 第二个)。这对减少噪音有很大帮助,regex已经很难读取了;-)

    你可能注意到我改变了主意 gsub gsub! ,并且摆脱了任务。通常,以 ! 将是那些不以 ,但在某种程度上,你必须更加注意使用它。在这种情况下, 返回一个包含替换项的新字符串, 格苏布! 替换是否到位。这里的另一点是,在ruby中,字符串是可变的,这与C#有细微的区别,但允许进行就地替换。

    一般来说,大部分的差异可以归结为三件事;DRY(不要重复你自己)在ruby中比在C#中走得更远,除非你需要,否则不要使用标点符号,通过尽可能少的打字(在降低可读性之前)来接受语言的简洁性