You could do it like this:
a = ["#","Feature","In order","As a","I want"]
File.open(file).each_line do |line|
line.chomp!
next if line.empty? || a.any? { |a| line =~ /#{a}/ }
end
Question
What's the best approach for ignoring some lines when reading/parsing a file (using Ruby)?
I'm trying to parse just the Scenarios from a Cucumber .feature file and would like to skip lines that doesn't start with the words Scenario/Given/When/Then/And/But.
The code below works but it's ridiculous, so I'm looking for a smart solution :)
File.open(file).each_line do |line|
line.chomp!
next if line.empty?
next if line.include? "#"
next if line.include? "Feature"
next if line.include? "In order"
next if line.include? "As a"
next if line.include? "I want"
Solution
You could do it like this:
a = ["#","Feature","In order","As a","I want"]
File.open(file).each_line do |line|
line.chomp!
next if line.empty? || a.any? { |a| line =~ /#{a}/ }
end
OTHER TIPS
The start_with?
method accepts multiple arguments:
File.open(file).each_line do |line|
next unless line.start_with? 'Scenario', 'Given', 'When', 'Then', 'And', 'But'
# do something with line.
end
You can replace most of your current loop with a single regular expression that uses alternation. You might also want to use String#chomp! as part of your conditional expression. For example:
File.open(file).each do |line|
next if line.chomp! =~ /^$|#|Feature|In order|As a|I want/
# something else
end
This reduces your block by six lines of code. Whether or not you find this alternative easier to read, it is certainly shorter and a bit more idiomatic. Your mileage may vary.
That's not that much help, but well, you might use array intersection for less code.
words = ["#", "Feature", "In order", "As a", "I want"]
File.open(file).each_line do |line|
line.chomp!
next if line.empty? || !(line.split & words).empty?
Use the abstract method
refctoring method! You could employ what ever technique ,clever or not-so-clever ,in the abstracted method.
File.open(file).each_line do |line|
line.chomp!
next if ignore(line)
end
def ignore line
#do whatever you like here, clever or straightforward.
#All the techniques others has posted could be applied here
end