This last bit would be true in most cases, but you'd be looping
through the lines of the file in memory rather than re-reading it.
This sounds like a great case for using an Enumerable mixin:
class Dataanalysis
include Enumerable
attr_reader :lines
attr_reader :emptylines
def initialize(filename)
@filename = filename
@content = File.readlines(@filename)
@lines = @content.size
@emptylines = @content.grep(/^\s*$/).size
end
def each(&b)
@content.each do |line|
if block_given?
b.call line
else
yield line
end
end
end
end
Then you can do fun things like:
1.9.3-head :034 > f = Dataanalysis.new('dataanalysis.rb')
=> #<Dataanalysis:0xa3d6210 @filename="dataanalysis.rb",
@content=["class Dataanalysis\n", " include Enumerable\n", "
attr_reader :lines\n", " attr_reader :emptylines\n", "\n", " def
initialize(filename)\n", " @filename = filename\n", " @content =
File.readlines(@filename)\n", " @lines = @content.size\n", "
@emptylines = @content.grep(/^\\s*$/).size\n", " end\n", "\n", " def
each(&b)\n", " @content.each do |line|\n", " if
block_given?\n", " b.call line\n", " else\n", "
yield line\n", " end\n", " end\n", " end\n", "\n", "end\n"],
@lines=23, @emptylines=3>
1.9.3-head :035 > f.lines
=> 23
1.9.3-head :036 > f.emptylines
=> 3
1.9.3-head :040 > f.each{|l| puts l.gsub(/\s+/,'*')}
class*Dataanalysis*
*include*Enumerable*
*attr_reader*:lines*
*attr_reader*:emptylines*
···
On Sun, Feb 3, 2013 at 8:03 PM, Soichi Ishida <lists@ruby-forum.com> wrote:
In addition to these, what if I want to apply specific regular
expressions to each of the lines?
say,
if line =~ /exp1/ then
# do stuff
else
# do stuff
end
In this case, the loop for all lines must be implemented, am I correct?
If the class methods dynamically take regular expression like
test = DataExtractor.new('file.txt')
test.apply_regexp(/exp1/)
Doesn't the loop need to be reactivated for each method like this?
*
*def*initialize(filename)*
*@filename*=*filename*
*@content*=*File.readlines(@filename)*
*@lines*=*@content.size*
*@emptylines*=*@content.grep(/^\s*$/).size*
*end*
*
*def*each(&b)*
*@content.each*do*|line|*
*if*block_given?*
*b.call*line*
*else*
*yield*line*
*end*
*end*
*end*
*
end*
1.9.3-head :041 > f.map{|l| l.gsub(/\s+/,'*')}
=> ["class*Dataanalysis*", "*include*Enumerable*",
"*attr_reader*:lines*", "*attr_reader*:emptylines*", "*",
"*def*initialize(filename)*", "*@filename*=*filename*",
"*@content*=*File.readlines(@filename)*", "*@lines*=*@content.size*",
"*@emptylines*=*@content.grep(/^\\s*$/).size*", "*end*", "*",
"*def*each(&b)*", "*@content.each*do*|line|*", "*if*block_given?*",
"*b.call*line*", "*else*", "*yield*line*", "*end*", "*end*", "*end*",
"*", "end*"]
and so on.
All this said, there is still a caveat: the size of the file under
analysis. If it's something smallish to medium, no problem. If it's a
4G log file -- then you'll likely have some issues.