1

for example, I have an array which is structured as follow:

my_array = [["..\\..\\..\\Source\\file1.c"], ["..\\..\\..\\Source\\file2.c"]]

This array is produced by this code:

File.open(file_name) do |f|
    f.each_line {|line|
      if line =~ /<ClCompile Include="..\\/
        my_array << line.scan(/".*.c"/)
      end
    }
  end

Later in the code I'm working on the array:

my_array .each {|n| f.puts n.gsub(/\\/,"//")}

As you can see, would like to replace all the backslashes with forward slashes on the elements within the array. The elements presents paths to source files. On the end I will output these paths within an other file.

I get this error:

undefined method `gsub' for [["..\\..\\..\\Source\\file1.c"], ["..\\..\\..\\Source\\file2.c"]]:Array (NoMethodError)

Any idea?

6
  • where does the "f" come from? Commented Nov 19, 2015 at 15:01
  • Use my_array.flatten.each instead (you have a multi-dimensional Array, an Array of Arrays, and flatten will make it a one-dimensional Array) Commented Nov 19, 2015 at 15:03
  • @bosskovic: Have improved the question (explained more detailed) so that you can see where "f" comes from Commented Nov 19, 2015 at 15:22
  • please try flattening the array as I suggested in my updated answer, and see if that works for you. Commented Nov 19, 2015 at 15:28
  • @bosskovic: yes it worked! ... cool method :) Commented Nov 19, 2015 at 16:15

3 Answers 3

1

You have an array of arrays, so if you want to keep it like that, you would need to have 2 loops.

Otherwise, if you change your variable to this: my_array = ["..\\..\\..\\Source\\file1.c", "..\\..\\..\\Source\\file2.c"] your code should work.


UPDATE

if you can not control my_array, and it is always an array of one item arrays, perhaps this is cleanest:

my_array.flatten.each {|n| puts n.gsub(/\\/,"//")}

What it does is transforms two-dimensional array in one-dimensional.

Sign up to request clarification or add additional context in comments.

1 Comment

Have tested it and it works! Didn't know about the "flatten" method .... cool , thx! :)
1
my_array.flatten.each { |n| f.puts n.tr('\\', '/') }

1 Comment

I like your use of String#tr, but would suggest my_array.each { |n| f.puts n.first.tr('\\', '/') } to avoid the creation of an unnecessary temporary array. (This is after a file with handle f is opened for writing.)
0

As others have pointed out, you are calling gsub on an array, not the string within it. You want:

my_array.each {|n| puts n[0].gsub(/\\/,"//")}

2 Comments

This only does the gsub on the first of the two nested arrays. It'd be better to use flatten or also iterate over the nested arrays. IMO it doesn't make much sense to hardcodedly only get the first nested array.
@Mischa, this seems a rather specific requirement. I don't know if the time required to write and test a method that will permit arbitrary levels of nesting is justified when the method's grater potential may never be realized. It's a balancing act.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.