From: Rick DeNatale Date: 2008-05-30T02:04:31+09:00 Subject: Re: How can a code block access an object's variables? On Thu, May 29, 2008 at 11:30 AM, Jacob Rubynovice wrote: > Dear Rubyists, > > I am a novice Ruby developer who is interested in figuring out a way to > design something like what is demonstrated below. The reason why > each_line would not work in this example is because when you pass a > block of code to the FileReader object, the memory (members of > FileReader) is not shared with the block of code that is sent to > FileReader. > > Maybe I have the wrong idea for how this would be designed. I just > think it would be very convenient to do this sort of thing because I > could re-use the code to open a file and read lines and only pass it > code blocks pertainant to what I want to do with those lines of code. > > Please note that I do not only want to do this for an open file/read > line script. It would also be useful if you were expanding an IP range > that exceeds what you could store into an array object because you could > write an each_host method that takes in a block of code that relates to > what you want to do to each host. > > class FileReader > > def initialize(fname, &block) > @filename = fname > end > def each_line(&block) > begin > source = File.new(@filename, "r") > rescue => err > exit > end > begin > while(line = source.readline) > > line.strip! > if((line == "") || (line =~ /[\t+\s+]/)) > next > end > block.call > end > rescue EOFError > source.close > rescue => err > puts "[!] #{err}" > exit > end > end This can be made much shorter using Ruby conventions: class FileReader def initialize(fname, &block) @filename = fname end def each_line source = File.open(@filename, "r") do |f| # this will automatically close the file f.each do | line | # This avoids having to check for end-of-file explicitly. line.strip! yield line unless ((line == "") || (line =~ /[\t+\s+]/)) end end rescue => err # Note that a method definition itself acts like begin/end puts "[!] #{err}" exit end end The two inner lines: line.strip! yield line unless ((line == "") || (line =~ /[\t+\s+]/)) could be combined as: yield line unless ((line.strip! == "") || (line =~ /[\t+\s+]/)) But I think that the two line form might be a little clearer. I'm not sure just what you expect the regex to be doing, as you've coded it it's going to skip any line which has at least one tab followed immediately by at least one whitespace character regardless of anything else in the line. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/