Powerful Rails 3 Templates

Blog ยป Powerful Rails 3 Templates

Posted on 30 Aug 2012 09:28

Rails 3 templates or Thor scripts can do any kind of modification on source code. As regular expressions can hunt for syntax patterns; you can replace existing methods with new definitions. For example:

def match_mtd(mtd)
/^\s*def (#{mtd})\s+((?!end).)*\s+end\s*$/m
end
 
gsub_file 'app/models/post.rb', match_mtd('create_permitted\?'), <<-CODE
 
  def \\1
    acting_user.signed_up?
  end
CODE
 
gsub_file 'app/models/post.rb', match_mtd('update_permitted\?'), <<-CODE
 
  def \\1
    owner_is? acting_user
  end
CODE
rake rails:template LOCATION=../my_template

Existing methods are found and replaced. Now you have your create_permitted? and update_permitted? methods.
This is extremely useful for automating the replacement of framework generated source code.

Notes:

  • In create_permitted\?, ? is escaped because it is inserted in a regular expression. In a regular expression ? only means match any character.
  • def \\1. Double escaped 1? If it's not escaped \1 means character with ascii code 1 and it gets replaced. \1 in a regex replacement means first match expression which is the method name here.

Ok. Ok. You cannot match any syntax with a regex. But it has untapped powers to handle most of the cases. ((?!end).)* means zero or more times something that's not 'end'. Let's analyize the expression.

/^\s*def (#{mtd})\s+((?!end).)*\s+end\s*$/m

\s* # 0 or more spaces
def (#{mtd}) # def <mtd>
\s+ # 1 or more spaces
((?!end).)* # 0 or more whatever that's not end
\s+ # 1 or more spaces
end # end
\s* # 0 or more spaces
$ # end of line
/m # match multiline

As you see this expression would not be good if there was an extra end used in the method definition.

Maybe the next idea should be to support Thor with Ruby parser?

If you like this page, please spread the word: diggdel.icio.usFacebook

You can contact me if you have questions or corrections.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License