tags:

views:

36

answers:

2

I've searched and not been able to find the right way of doing what I'm trying to. I read a file line by line and want to create a new object from a regex on each line. I'm not using an XML parser because the data is not well formed and listed below is all I need to get from each line.

I can't seem to get scan to return the result of the block. It just returns the original string. I have temporarily gotten around it by creating this temp variable, but I'm sure there is a better way.

enum = File.foreach(filename)  

enum.map do |line|
   temp = nil
   line.scan(/<cab id="(\w+)" updates="(\d+)"/) { |a,b| temp = Cab.new(a,b) }
   temp
end

Thanks for any help.

A: 

I would do:

enum.map {|line| Cab.new(*line.match(/<cab id="(\w+)" updates="(\d+)"/)[1,2]) }

or if I wanted it to be more readable:

enum.map {|line|
  line =~ /<cab id="(\w+)" updates="(\d+)"/
  Cab.new($1, $2)
}
mckeed
Thanks mckeed for the two ways of writing it. This gives the result I was looking for. I think I should go and have a look into the match stuff you've demonstrated.
Oli
Yeah, I should have explained more that match (or the =~ shorthand) is what you use when you want to match a regex against a string once, whereas scan is for when you need to match it many times against one string. If your source file didn't have line breaks between matches, you could still use scan on the entire file contents to get all the matches in succession.
mckeed
A: 

scan + map maybe?

line.scan(/<cab id="(\w+)" updates="(\d+)"/).map { |a,b| Cab.new(a,b) }
stereofrog
Thanks stereofrog, but that returns an array with a single entry, whereas I actually want to try and just return result of the block by itself.
Oli