Newbie Question: - Parse my commands...

Discussion in 'Ruby' started by paytonrules, Sep 12, 2006.

  1. paytonrules

    paytonrules Guest

    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?
    paytonrules, Sep 12, 2006
    #1
    1. Advertising

  2. paytonrules wrote:

    > 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?


    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.
    Vidar Hokstad, Sep 13, 2006
    #2
    1. Advertising

  3. On Wed, Sep 13, 2006 at 08:10:35AM +0900, Vidar Hokstad wrote:
    >
    > paytonrules wrote:
    >
    > > 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?

    >
    > 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

    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.
    Logan Capaldo, Sep 13, 2006
    #3
  4. paytonrules

    paytonrules Guest

    Logan Capaldo wrote:
    > On Wed, Sep 13, 2006 at 08:10:35AM +0900, Vidar Hokstad wrote:
    > >
    > > paytonrules wrote:
    > >
    > > > 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?

    > >
    > > 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

    > 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.


    > > 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?
    paytonrules, Sep 13, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Pfaff

    Re: man pages for C commands (GCC commands)

    Ben Pfaff, Jun 24, 2003, in forum: C Programming
    Replies:
    4
    Views:
    3,944
    Thomas Stegen
    Jun 28, 2003
  2. googleboy
    Replies:
    2
    Views:
    279
    Christopher T King
    Jul 14, 2004
  3. Tim Stanka
    Replies:
    1
    Views:
    781
    Jeff Epler
    Aug 2, 2004
  4. Replies:
    19
    Views:
    1,092
    Daniel Vallstrom
    Mar 15, 2005
  5. 7stud --

    optparse: parse v. parse! ??

    7stud --, Feb 20, 2008, in forum: Ruby
    Replies:
    3
    Views:
    168
    7stud --
    Feb 20, 2008
Loading...

Share This Page