From: Rein Henrichs Date: 2010-06-08T05:20:05+09:00 Subject: Re: questions of idiom A work-in-progress Ruby Style Guide is available here: http://github.com/chneukirchen/styleguide/blob/master/RUBY-STYLE A few suggestions from your code samples (some are Ruby-specific, some are general "clean code" suggestions): 1. Use snake_case for variable and method names, not camelCase. Use SHOUTING_SNAKE_CASE for constants, CamelCase for classes and modules. 2. Don't needlessly shorten variable names (like @tokID). The goal is not brevity but clarity. 2. Do not start variable names with underscores. 3. Use string interpolation ( "#{self.class.name}: #{@token_id}" ) rather than concatenation via +. 4. Use puts instead of print with an "\n", see also #3. 5. Use literals where available. [] instead of Array.new, "" instead of String.new, {} instead of Hash.new. 6. Take advantage of Ruby's sane conditional evaluation semantics. Instead of `if !foo.nil?`, simply `if foo`. 7. Do not put extensive conditional logic in #each blocks. Rather, extract such logic into a method with an intention revealing name. 8. Take advantage of Enumerable methods that are more specific to your needs than #each. For instance, the findMatch method might use #detect instead of #each. 9. Variables do not need to be initialized. You assign nil to a number of variables and then later reassign them. This is unnecessary. 10. Use do/end for multiline blocks and {} for single-line blocks. 11. Write query methods to wrap complex truthiness expressions in intention revealing methods. For instance: md = rule.re.match(@buff) if !md.nil? && md.pre_match.length == 0 could be changed to: # Define query method class Rule def matches?(buffer) md = rule.re.match(@buff) md && md.pre_match.empty? end end # Use query method if rule.matches?(@buff) Note that .empty? is often a more expressive replacement for .length == 0 11. Use a_string.dup instead of String.new(a_string) 12. Alternatively, use non-destructive methods to avoid mutable state concerns. 13. Do not put a space between a method and its parenthesized arguments. Good: foo(bar) Bad: foo (bar) Also good (unless clarity suffers): foo bar 14. Do not use parallel assignment ( foo, bar = 1, 2 ) except where doing so results in a clear improvement in the clarity (rather than brevity) of your code. Finally, there is prior art that may interest you. Ruby parser/lexers include: racc treetop ripper grammar All are available as gems and are probably available on Github as well. -- Rein Henrichs http://puppetlabs.com http://reinh.com