From: Robert Klemme Date: 2005-09-26T18:46:41+09:00 Subject: Re: Overloading Ben wrote: > I'm a C++ programmer learning Ruby. I would like to make a class that > extracts patterns from a file, and returns an array of values. I > have: > > class Extracter > def initialize(pattern, location) > @pattern = pattern > @loc = location > end > def extract(stream) > pats = Array.new > stream.each_line do |line| > if line =~ @pattern then > pats << $~[@loc] > end > end > pats > end > end > > cppFile = File.new("foo.cpp") > incEx = Extracter.new(/#include\s*[<"](.*)[>"]/, 1) > includesArr = incEx.extract(ccpFile) > > So far, so good. If not, let me know what I've done wrong. Next, I > want to extend the Extracter class to hold an array of patterns and > locations, or a Proc parser that will return the interesting value > (this is for lines that are tougher than regexp). How do I create a > constructor that will take different types and create the appropriate > arrays internally? The options I see are: > > 1) Call .class.to_s on each parameter to match the type: > "pattern.class.to_s =~ /Array/ then # I have an array of > regexp 2) Use a non-trvial data structure to map symbols to types > 3) Use different functions to fill out my extracter: > def add_array > def add_parser > > What am I missing? Am I doing this entirely wrong for Ruby? General stuff about method overloading and C++ like constructs: http://www.rubygarden.org/ruby?MethodOverloading http://www.rubygarden.org/ruby?RubyFromCpp In your case I'd probably do it differently. Maybe something like this: def extract(io) result = [] io.each_line do |line| dat = yield line and result << dat end result end includes = File.open("foo.cpp") do |io| extract io {|line| /#include\s*[<"](.*)[>"]/ =~ line and $1 } end Btw, your regexp might be too greedy because you use ".*". Alternatives that might work: /#include\s*[<"](.*?)[>"]/ /#include\s*[<"]([^>"]*)[>"]/ Kind regards robert