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

ruby向数组添加变量值

  •  2
  • Mark  · 技术社区  · 14 年前

    我有一个Ruby1.8.6脚本,它应该采用包含路径的文件名,创建文件夹,然后将文件移动到文件夹中。我有一个数组 created_paths 以跟踪创建的文件夹(脚本将遍历许多文件)。我有一个问题添加到 创建的路径 数组。

    created_paths = Array.new
    file_name = "first\\second\\third.txt"
    parts = file_name.split('\\')
    tmp_path = ""
    parts.each_with_index { |part,i|
        if i == (parts.length - 1)                
            # copy file to new dir structure
        else
            tmp_path << part << "/"
            if !created_paths.include?(tmp_path)                   
                puts "add to array: #{tmp_path}"
                created_paths.push(tmp_path)
                # create folder
            end
        end
    }
    puts "size=#{created_paths.length}\n"
    created_paths.each { |z| print z, "\n " }
    

    当我推 tmp_path 创建的路径 数组的引用 TMP-路径 已添加,而不是值。关于循环的第二次迭代 created_paths.include?(tmp_path) 是真的。我如何得到 TMP-路径 存储在我的数组中,或者可能缺少作用域问题?

    我的输出:

    add to array: first/
    size=1
    first/second/
    

    我的例外输出:

    add to array: first/
    add to array: first/second/
    size=2
    first/
    first/second/
    
    3 回复  |  直到 14 年前
        1
  •  5
  •   Mladen Jablanović    14 年前

    你可以使用 tmp_path.dup 在将字符串推送到数组之前克隆它。

    但我不明白你为什么要做所有的事情(保留创建目录的列表)。看一看 FileUtils#mkdir_p ,则向它传递要创建的目录的路径,并创建该目录以及所有丢失的父目录。

        2
  •  2
  •   Beanish    14 年前

    当我将tmp_path推送到创建的路径数组时,似乎已经添加了对tmp_path的引用,而不是值。

    ruby中的所有东西都是引用的。

    当您使用<<时,您将连接到字符串。使用dup方法应该对你有用。

    mystring = "test"
    myarray = []
    
    5.times do |x|
      mystring << x.to_s
      myarray << mystring
    end
    
    puts myarray
    

    在上面的代码片段集中,<<将字符串赋值为=并查看输出中的差异。

    同样作为ruby的一个附加说明,您可以在打印时使用puts添加换行符。 所以 created_paths.each { |z| print z, "\n " }

    可以阅读 created_paths.each { |z| puts z }

        3
  •  1
  •   AShelly    14 年前

    问题是这一行正在修改原始字符串对象。数组保存对该对象的引用。

      tmp_path << part << "/"    
    

    要避免这种情况,您需要创建一个新对象。或者在添加路径时执行此操作

    created_paths.push(tmp_path.dup)
    

    或做:

    tmp_path += part + "/"
    

    不管是哪种方式,都是创建一个新的字符串对象,而不是修改现有的字符串对象。