# Newbie Question: - Parse my commands

**URL:** <https://www.ruby-forum.com/t/newbie-question-parse-my-commands/68449>\
**Category:** Ruby\
**Created:** [September 12, 2006, 8:15pm UTC](https://www.ruby-forum.com/t/newbie-question-parse-my-commands/68449 "2006-09-12T20:15:39Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![paytonrules](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/838e76/32.png) [@paytonrules](https://www.ruby-forum.com/u/paytonrules)\
**Post date:** [September 12, 2006, 8:15pm UTC](https://www.ruby-forum.com/t/newbie-question-parse-my-commands/68449/1 "2006-09-12T20:15:39Z")

</div>

Okay I’m trying to take our old scripting software and quickly move it  
up in the world. We have a program that takes as a parameter a script  
file, parses it and runs it for unit testing purposes. There are  
several problems:

1. Each script file requires setting up a large database.
2. No way to debug a file short of setting breakpoints in C++ on the  
parser itself.
3. No way - this is the big one - to just run an individual command  
and get instant feedback.

Now in the meantime I’ve been playing with Ruby and ROR and I think I  
should be able to use the irb command to create this pretty quickly,  
but I’m not quite sure how. Our commands in the .scr file currently  
look like this

ObjectName.Make(param1, param2, param3, param4)

The first step, which I’m doing now, is to take our executable program  
and break the parsing engine into a DLL. That’s easy. I can then  
create a quick ruby program so I could do this:

irb  
load ‘rubyProg’

parse ObjectName.Make(param1, param2, param3, param4)

The rubyProg could work this way - but I’m pretty sure I can go one  
step farther with ruby and just type:

ObjectName.Make(param1, param2, param3, param4)

through ruby extensions. The question is - how do I have the  
interpreter pass on any code to the parser ruby can’t handle it?

---

<div class="post-metadata">

**Author:** ![paytonrules](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/838e76/32.png) [@paytonrules](https://www.ruby-forum.com/u/paytonrules)\
**Post date:** [September 13, 2006, 1:12am UTC](https://www.ruby-forum.com/t/newbie-question-parse-my-commands/68449/2 "2006-09-13T01:12:14Z")

</div>

paytonrules wrote:

> The rubyProg could work this way - but I’m pretty sure I can go one  
> step farther with ruby and just type:
> 
> ObjectName.Make(param1, param2, param3, param4)
> 
> through ruby extensions. The question is - how do I have the  
> interpreter pass on any code to the parser ruby can’t handle it?

method\_missing() can be used for this to some extent. It depends on how  
exact you want the syntax. If you can get away with changing the object  
names so that they start with a lowercase letter it’s cleaner. In Ruby,  
a capital first letter of a name indicates a constant, which means you  
need some extra uglyness to handle that.

With a lowercase first letter in your object names you can do:

class MissingProxy  
def initialize ob  
@ob = ob  
end

def method\_missing(sym,\*args)  
# Call your script processor here.  
puts “PROCESS: #{@ob.to\_s}.#{sym.to\_s}(#{args.join(’,’)})”  
end  
end

def method\_missing(sym,\*args)  
MissingProxy.new(sym)  
end

myObject.Make(‘test’,123)

If, on the other hand you don’t want to rewrite anything, you can wrap  
the statements like this:

begin  
MyObject.Make(‘test’,123)  
rescue NameError =\> n  
eval("#{n.name} = MissingProxy.new(:#{n.name})")  
retry  
end

I’d consider both of these methods fairly ugly. They make trapping  
errors in your Ruby code tricky, as any misspelled object/class names  
will trigger your script interpreter instead of giving an error, but it  
does give a lot of flexibility.

An alternative that is less intrusive is to wrap the latter method  
missing in a module:

module Script  
def method\_missing(sym,\*args)  
MissingProxy.new(sym)  
end  
end

And add the module name to any script command:

Script.MyObject.Make(‘test’,123)

If you do it this way at least misspellings etc. in your Ruby code is  
less likely to trigger your script processing, but then I guess you  
could just as well do it the way you suggested in the first place.

Vidar.

---

<div class="post-metadata">

**Author:** ![paytonrules](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/838e76/32.png) [@paytonrules](https://www.ruby-forum.com/u/paytonrules)\
**Post date:** [September 13, 2006, 1:36am UTC](https://www.ruby-forum.com/t/newbie-question-parse-my-commands/68449/3 "2006-09-13T01:36:15Z")

</div>

On Wed, Sep 13, 2006 at 08:10:35AM +0900, Vidar H. wrote:

> > parse ObjectName.Make(param1, param2, param3, param4)  
> > method\_missing() can be used for this to some extent. It depends on how  
> > end
> 
> retry  
> end  
> To handle the MyObject case, you needs simply define const\_missing  
> instead of method\_missing, no need to rescue name error.
> 
> I’d consider both of these methods fairly ugly. They make trapping  
> errors in your Ruby code tricky, as any misspelled object/class names  
> will trigger your script interpreter instead of giving an error, but it  
> does give a lot of flexibility.

Agreed.

---

<div class="post-metadata">

**Author:** ![paytonrules](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/838e76/32.png) [@paytonrules](https://www.ruby-forum.com/u/paytonrules)\
**Post date:** [September 13, 2006, 8:42pm UTC](https://www.ruby-forum.com/t/newbie-question-parse-my-commands/68449/4 "2006-09-13T20:42:05Z")

</div>

Logan C. wrote:

> > > 
> > 
> > ```
> > @ob = ob
> > 
> > ```
> > 
> > end  
> > eval("#{n.name} = MissingProxy.new(:#{n.name})")  
> > Agreed.  
> > I’d consider both of these methods fairly ugly. They make trapping  
> > errors in your Ruby code tricky, as any misspelled object/class names  
> > will trigger your script interpreter instead of giving an error, but it  
> > does give a lot of flexibility.

I agree - but the C++ parser is allowed to return errors no?

To put it another way - lets assume I do the const\_missing. Parse will  
return errors - couldn’t I use the parse errors to deterimine “is this  
a parse error or is this a Ruby error”?

I realize I’m not explaining myself well - perhaps because I’m really  
just experiementing with this to make sure I’ve got a good idea. We’ve  
already got an old parser executable that parses script files. I just  
want to use irb and ruby to glue this and make a statement-by-statement  
runtime interpreter. Would a better design be to include the irb in my  
application and work the other way around?
