# Ruby newby

**URL:** <https://www.ruby-forum.com/t/ruby-newby/96102>\
**Category:** Ruby\
**Created:** [December 8, 2005, 5:35pm UTC](https://www.ruby-forum.com/t/ruby-newby/96102 "2005-12-08T17:35:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![schmitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9e8a1a/32.png) [@schmitt](https://www.ruby-forum.com/u/schmitt)\
**Post date:** [December 8, 2005, 5:35pm UTC](https://www.ruby-forum.com/t/ruby-newby/96102/1 "2005-12-08T17:35:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![schmitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9e8a1a/32.png) [@schmitt](https://www.ruby-forum.com/u/schmitt)\
**Post date:** [December 8, 2005, 6:04pm UTC](https://www.ruby-forum.com/t/ruby-newby/96102/2 "2005-12-08T18:04:13Z")

</div>

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
