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
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.
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+)] @table << @current if @current
@current= Reservation.new()
end
end
end
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+)] @table << @current if @current --Don’understand? If @current is
emtpy
@current= Reservation.new()
end
end
end
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
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.