From: Joel VanderWerf Date: 2006-02-18T14:49:37+09:00 Subject: Re: define_method fun Patrick Ritchie wrote: > Hi All, > > I just setup the following in one of my classes, I'll let the code speak > for itself: > > ["<", "<=", ">", ">=", "==", "<=>"].each do |op| > define_method(op) { |comparison| eval "#{self.order} #{op} > #{comparison.order}" } > end > > Ruby continues to impress me with it's ability to do so much in so few > amazing readable lines of code. > > Are their any good reasons not to declare my op methods this way? Is > their an even more efficient way to achieve the same effect? It helps to pull the eval out of the define_method: module Order attr_reader :order def initialize order @order = order end end class EvalInside include Order ["<", "<=", ">", ">=", "==", "<=>"].each do |op| define_method(op) { |comparison| eval "#{self.order} #{op} #{comparison.order}" } end end class EvalOutside include Order ["<", "<=", ">", ">=", "==", "<=>"].each do |op| eval "define_method(:#{op}) { |comparison| self.order #{op} comparison.order }" end end require 'benchmark' inside = [] outside = [] 1000000.times do |i| order = rand(1) inside << EvalInside.new(i) outside << EvalOutside.new(i) end Benchmark.bmbm do |bm| bm.report("eval inside") do inside.sort end bm.report("eval outside") do outside.sort end end Rehearsal ------------------------------------------------ eval inside 17.280000 0.030000 17.310000 ( 18.088599) eval outside 2.170000 0.010000 2.180000 ( 2.254999) -------------------------------------- total: 19.490000sec user system total real eval inside 17.260000 0.010000 17.270000 ( 17.873053) eval outside 2.150000 0.010000 2.160000 ( 2.248230) -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407