From: Logan Capaldo Date: 2006-10-11T23:04:48+09:00 Subject: Re: ERB as a macro pre-processor? On Wed, Oct 11, 2006 at 02:40:58PM +0900, Rich Morin wrote: > "The Ruby Way" (pp. 43-45) shows a couple of different ways > to generate methods dynamically (using eval). Looking at the > examples, I began to wonder about different Ways To Do It. > > One possibility that occurred to me is to use ERB as a macro > pre-processor. The book suggests the following code: > > if platform == Windows > def my_action > action1 > end > if platform == Linux > def my_action > action2 > end > else > def my_action > default_action > end > end > > Although this is approach is direct and simple, it seems like it > wouldn't scale very well, given multiple variations. However, I > think that the following approach might: > > > % cat erb_ml > #!/usr/bin/env ruby > > require 'erb' > > def action_D; print "default action\n"; end > def action_L; print "Linux action\n"; end > def action_W; print "Windows action\n"; end > > action = { :Linux => 'action_L', > :Windows => 'action_W' } > > template = ERB.new <<-EOF > def my_action > <%= action[platform] || 'action_D' %> > end > EOF > > for platform in [ :Linux, :Windows, :Plan9 ] do > eval template.result(binding) > print "#{platform.to_s}: " > my_action > end > > % erb_ml > Linux: Linux action > Windows: Windows action > Plan9: default action > > > Obviously, the "action" hash could be replaced by other > code-generation and/or -retrieval methods. Is anyone > here using ERB in this manner? Are there any caveats > or alternative approaches that I should be aware of? Bah I say! How does that saying go, "Replace conditionals with polymorphism"? class Platform end class Linux < Platform def define_methods def a puts "linux" end end end class Windows < Platform def define_methods def a puts "windows" end end end class Platform def self.get_platform case RUBY_PLATFORM when /linux/ Linux when /win32/ Windows end end end platform = Platform.get_platform.new platform.define_methods