The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Why I Love Ruby, Episode 12

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Michael Granger

Posts: 53
Nickname: ged
Registered: Sep, 2005

Michael Granger is just another Ruby Hacker.
Why I Love Ruby, Episode 12 Posted: Nov 2, 2005 7:04 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Michael Granger.
Original Post: Why I Love Ruby, Episode 12
Feed Title: devEiate
Feed URL: http://deveiate.org/feed/rss/blog
Feed Description: A blog about Ruby, codecraft, testing, linguistics, and stuff. Mostly stuff.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Michael Granger
Latest Posts From devEiate

Advertisement

I’ve been doing quite a lot of thinking in Java for work lately, and I’m constantly amazed at how much effort it take to express anything useful above the class level of abstraction. The reflection API is a torture device. There’s so much time spend coddling the compiler, making it understand what you’re trying to do, that it’s often quicker to just stop trying to express things at a higher level of abstraction and just do everything by hand. Both of the Java IDEs I’ve used have code-generation facilities to make this less painful, but dependency on an IDE is a symptom of language deficiency, and generated boilerplate source reduces the expressiveness of the code. It’s the difference between an Army manual and a Mark Helprin novel.

Anyway, I’ve been working on both the FaerieMUD natural language generation code and the OOParser lately after work, and I’ve found a few new tricks for doing delegation that make me remember why I love Ruby.

The first is a way of optimizing delegation.

The OOParser class defines a domain-specific grammar language to express the rules for a top-down parser. In order to support the goal of making truly object-oriented parsers, rules must be able to be overridden by subclasses of the parent parser class, and I wanted to be able to use other tricks like #method_missing and aliases with rules as well, so they had to be implemented as methods. So the rules become Rule objects, and each Rule object’s #match method is delegated to by the correspondingly-named method of the parser object which contains them.

For example:

class IntegerParser < OOParser
  grammar {
    default :integer

    def_rule :integer, "<decimal>" do |match, state|
      state.log.debug "Match is: %p" % [match]
      return Integer( match[:decimal] )
    end
    def_rule :decimal, /\d+/
  }
end

This defines a parser with two rules: integer and decimal. These are instance methods of the parser objects, and can be used as methods to enter the parse at any point:

ip = IntegerParser.new

rval = ip.decimal( "15" )
# => "15"

Not a very glamourous example, but I hope you can see how that would be useful when building parsers for more complex targets.

Anyway, on to the delegation bit. Usually, delegation happens as a kind of handoff from the receiving object to the delegated one, e.g.,

def foo( *args )
  @delegatee.foo( *args )
end

This means that every call to #foo becomes two method calls, which isn’t normally a problem. In the case of a recursive-decent parser, however, where rules may be called many hundreds of times in the course of a typical parse, it can be. So OOParser uses Ruby’s superlative reflection to install the delegated object’s method directly into the containing object, making the call collapse back into one invocation:

# A bit simplified for demonstration
klass = parser_subclass
grammar.rules.each do |name,rule|
    block = rule.method( :match ).to_proc
    klass.__send__( :define_method, name, block )
end

I’ve run out of time to post the second example, but I’ll continue this in a later post.

Read: Why I Love Ruby, Episode 12

Topic: Refactoring Rails... coming soon Previous Topic   Next Topic Topic: Note to the M.E.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use