ruby добавление значения переменной в массив - PullRequest
2 голосов
/ 09 марта 2010

У меня есть скрипт на Ruby 1.8.6, который должен принимать имя файла, содержащее путь, создавать папки, а затем перемещать файл в папки. У меня есть массив created_paths для отслеживания созданных папок (скрипт будет перебирать множество файлов). У меня проблема с добавлением в массив 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 в массив created_paths, кажется, что добавлена ​​ссылка на tmp_path, а не значение. На второй итерации цикла created_paths.include?(tmp_path) возвращает True. Как я могу получить значение tmp_path для хранения в моем массиве, или, возможно, есть проблема с областью действия, которую я пропускаю?

Мой вывод:

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

Мой исключенный вывод:

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

Ответы [ 3 ]

5 голосов
/ 09 марта 2010

Вы можете использовать tmp_path.dup для клонирования строки перед передачей в массив.

Но я не понимаю, зачем вы все это делаете (ведение списка созданных каталогов). Взгляните на FileUtils # mkdir_p , вы передадите ему путь к каталогу, который вы хотите создать, и он создаст его вместе со всеми отсутствующими родительскими каталогами.

2 голосов
/ 09 марта 2010

Когда я помещаю tmp_path в массив созданного пути, кажется, что добавлена ​​ссылка на tmp_path, а не значение

Все в рубине по ссылке.

Когда вы используете <<, вы объединяете строку.Использование метода dup должно работать на вас.</p>

mystring = "test"
myarray = []

5.times do |x|
  mystring << x.to_s
  myarray << mystring
end

puts myarray

В приведенном выше фрагменте установите << для назначения строки в = и посмотрите разницу в выводе. </p>

Также в качестве примечания в ruby ​​вы можете просто использовать put для добавленияперевод строки при печати.чтобы created_paths.each { |z| print z, "\n " }

мог читать created_paths.each { |z| puts z }

1 голос
/ 09 марта 2010

Проблема в том, что эта строка модифицирует исходный строковый объект. Массив содержит ссылку на этот объект.

  tmp_path << part << "/"    

Чтобы избежать этого, вам нужно создать новый объект. Либо сделайте это, когда вы добавите пути

created_paths.push(tmp_path.dup)

Или сделать:

tmp_path += part + "/"

В любом случае, вы создаете новый строковый объект, а не модифицируете существующий.

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