From: Michael Neumann Date: 2001-07-19T18:36:13+09:00 Subject: [ruby-talk:18107] Re: Best way to prevent infinite loops... Sean Chittenden wrote: > > > Howdy. What's the best way to prevent infinite loops in Ruby? > > > > Don't write one. :) > > I wish I could... I'm using a recursive regexp to remove all > tags from a template and tags can include tags. > > > I guess I'd ask: what's the driver of the loop? Is it the test for > > some_action, or is it the count, or both. If the count is incidental, > > then I'd tuck it away inside the loop (although possibly making it > > slightly shorter) > > In a nut shell, here's what I'm doing: > > tmpl = large_string > tag_re = Regexp.new('\<\?tmpl\.([^\s\?]*)\s*(.*?)\s*\?\>') > loop_count = 0 > while md = tag_re.match(tmpl) > if loop_count > @max_num_iteration > raise(RuntimeError, "Too many iterations") > else > loop_count += 1 > end > ... > tag = md.to_a[0] > ... > tmpl.gsub!(/#{Regexp.escape(tag)}/, val) > ... > end def loop_max(max_iter) i = 0 catch(:exit) { loop { if i > max_iter raise RuntimeError, "Too many interations" else yield end i += 1 } } end tmpl = large_string tag_re = Regexp.new('\<\?tmpl\.([^\s\?]*)\s*(.*?)\s*\?\>') loop_max(@max_num_iteration) do throw :exit unless md = tag_re.match(tmpl) ... tag = md.to_a[0] ... tmpl.gsub!(/#{Regexp.escape(tag)}/, val) ... end Or instead of "throw" you could use the return value of the block as exit condition. Another solution would be to use timeout: require "timeout" timeout(10) { ... } Regards, Michael -- Michael Neumann merlin.zwo InfoDesign GmbH http://www.merlin-zwo.de