Ruby newby


#1

Hi,

I’m trying to write a parser for cooking recipes.
It looks like this:


require ‘bspmess’
class Parser

STATES = [ :FIND_START, :SCAN_HEADER]

methods = { :FIND_START => self.find_start,
            :SCAN_HEADER => self.scan_header
          }

def initialize(msg)
    @msg = msg
    @state = :FIND_START
end

def run
    @msg.each { |line|
         scan line
    }
end

def scan(line)
    methods[@state].call(line)
end

def find_start(line)
    puts "find_start "
    @state = :SCAN_HEADER
end

def scan_header(line)
    puts "scan header"
end

end

p = Parser.new(MSG)
p.run


I get an error when the scan method is called first:
undefined method `find_start’ for Parser:Class (NoMethodError)

Who can help me ?

Thanks in advance,

Uwe


#2

On Fri, Dec 09, 2005 at 01:32:35AM +0900, Uwe S. wrote:

methods = { :FIND_START => self.find_start,
            :SCAN_HEADER => self.scan_header
          }

This doesn’t do what you want. It’s trying to call the “find_start”
and “scan_header” methods on the Parser Class object. There are
several possibilities to do this correctly:

  1. Call self.instance_method(:find_start) to get an unbound method,
    which you’ll need to #bind before calling it.

  2. Construct your “methods” table in #initialize, and use
    self.method(:find_start) to get a bound method.

  3. Don’t build a method table at all. Do this instead:

def scan(line)
self.send(@state,line)
end

regards,
Ed