Parse a file through a class

Trying to Parse a file by running through a class.
I am not sure when I read threw the file if it should be placed in a
hash or and array. but some of these reservations are in a hash format.
Maybe I should have each reservations it’s own hash but not sure I have
the skills to get it done. Thought I would ask and see if I could get
some help. Have attached sample of test.log

#!/usr/bin/env ruby
class Line
attr_accessor :state, :id, :qid, :host1, :host2

def initialize(state, id, qid, host1, host2)
@state = state
@id = id
@qid = qid
@host1 = host1
@host2 = host2
end

def to_s
“#{@state} (#{@id}): #{@qid} #{@host1} #{@host2}”
end
end

def parse(lines)
lines.each do |text|
puts Line.new(text)
end
end

File.open(‘test.log’) do |f|
parse(f)
end

Hi:

That’s an interesting way to do it. I’m not sure, but I think you’ll
get an error because you’re passing a line of text to the initialize
method, and the initialize() wants 5 arguments. Usually, people do it
something like this:

File.open(‘test.log’) do |f|
f.eachline do |l|
field_array = split(l, “,”) #comma delimited string
@state = field_array[0]
@id = field_array[1]
etc.
end
end

I’m rusty on my syntax, but ruby has some really awesome methods for
dealing with hashes and arrays. You might want to use a hash:

hash = {}

hash[:state] = field_array[1]

If you look at the methods of the hash and aray objects, you may even
find a one line way to smash all the array values into a hash in one
line.

Good luck,
Eric

Tom Thomas wrote in post #1183438:

Trying to Parse a file by running through a class.
I am not sure when I read threw the file if it should be placed in a
hash or and array. but some of these reservations are in a hash format.
Maybe I should have each reservations it’s own hash but not sure I have
the skills to get it done.

class Reservation
attr_accessor :state, :id, :qid, :host1, :host2

def add(name,value)
meth=(name+"=").to_sym
self.send(meth,value) if self.respond_to?(meth)
end
def to_s() “#{@state} (#{@id}): #{@qid} #{@host1} #{@host2}” end
end

class Scanner
def scan(fn)
@current=nil
@table=[]
File.open(‘test.log’) do |f|
f.each_line do |l|
spl = (l.strip!).split(/\s+/,3)
scan_line(spl,l)
end
end
@table << @current if @current
@table
end
def scan_line(l,str)
if l.size == 3 && l[1]=="="
name,_,value=*l
@current.add(name,value) if @current
elsif str =~ /reservations[(\d+)]:confused:
@table << @current if @current
@current= Reservation.new()
end
end
end

puts Scanner.new.scan(‘test.log’)

All thanks with some examples as I have shown some something different.
@Regis thanks and appreciate your example.
Can follow all but a couple line and hope you could explain it to me.
Have add some comments beside the line of code in question.

class Scanner
def scan(fn)
@current=nil
@table=[]
File.open(‘test.log’) do |f| --Why would pass file name here when it
was passed below with puts
f.each_line do |l|
spl = (l.strip!).split(/\s+/,3) —Here you trip
leading/trailing whitespaces and then split on space which inext first
three items
scan_line(spl,l) – Don’t understand what happens here? Take
spl[0…2}, l but waht does that do?
end
end
@table << @current if @current --Don’understand? If @current is
emtpy
@table
end
def scan_line(l,str)
if l.size == 3 && l[1]=="="
name,_,value=*l --what’s with *1? I gues to show itself
@current.add(name,value) if @current --Don’understand? If @current
is emtpy
elsif str =~ /reservations[(\d+)]:confused:
@table << @current if @current --Don’understand? If @current is
emtpy
@current= Reservation.new()
end
end
end

puts Scanner.new.scan(‘test.log’)

Appreciate you help with learning Ruby

Thanks,

in the class how would I look at @host1 and if it contains a specific ip
address then add this “#{@state} (#{@id}): #{@qid} #{@host1} #{@host2}”
into and array and count how many as well.
Would I define a new method within the class to do it?

def num
if @host1.include?(“13.10.50.14”)
n =+ 1
ip_count << “#{@state} (#{@id}): #{@qid} #{@host1} #{@host2}”
pp ip_count
end
end

Tom Thomas wrote in post #1183463:

File.open('test.log') do |f| --Why would pass file name here when it

was passed below with puts

my mistake :), you can use fn parameter

scan_line(spl,l) – Don’t understand what happens here? Take
spl[0…2}, l but waht does that do?

call scan_line() method, with the list of word and the line readed

@table << @current if @current --Don'understand? If @current is emtpy
@current.add(name,value) if @current  --Don'understand? If @current
@table << @current if @current  --Don'understand? If @current is

This is a inline form of if :

instruction if condition

is same than

if condition
instruction
end

There are same inline form for while, rescue (as in perl lang) …
i+=1 while i<10
i=a/b rescue nil
i=(a/b rescue 999)
a=[] unless a
sleep 0.1 while queue.size>100 if queue.size>200

( sorry for my english, writing in ruby is easier for me :slight_smile: