Re-evaluating a 'case'

I was reminded of this problem by the recent 'breaking out of case’
thread. I have a ‘case’ statement that evaluates a condition:

case cond
when ‘thing1’
…do thing1 stuff…
when ‘thing2’
…do thing2 stuff…
cond = 'thing1’
end

The ‘thing2’ clause changes the value of ‘cond’, so I want to be able
to bounce back to the top and re-evaluate the case. The way I ended up
doing it was:

begin
case cond
when ‘thing1’
…do thing1 stuff…
when ‘thing2’
…do thing2 stuff…
cond = 'thing1’
raise
end

rescue
retry
end

Raising an exception on a non-error condition seems sort of hackish,
and I’m also worried that doing this a lot could have performance
impacts.

Thoughts on other ways to do this?

Dan

···


/^Dan Debertin$/
airboss@nodewarrior.org | Did I sleep a little too late,
www.nodewarrior.org | or am I awake? --Byrne

Dan Debertin airboss@nodewarrior.org writes:

The ‘thing2’ clause changes the value of ‘cond’, so I want to be able
to bounce back to the top and re-evaluate the case. The way I ended up
doing it was:

Well, there’s always…

 a = 1
 begin
   case a
   when 1
     puts 1
     a = 2
     redo
   when 2
     puts 2
   end
 end while false
 puts "done"

but I’m not sure that’s much clearer.

Possibly you might want a simple state machine…

Dave

begin
case cond
when ‘thing1’
…do thing1 stuff…
when ‘thing2’
…do thing2 stuff…
cond = ‘thing1’
raise
end

rescue
retry
end

Raising an exception on a non-error condition seems sort of hackish, and
I’m also worried that doing this a lot could have performance
impacts.

Thoughts on other ways to do this?

Dan

The redo keyword might help here, no? (I’ve never used it so I’m not sure.)

Gavin

I don’t think its better, and in some ways worse :slight_smile:

casefunc = proc { |cond|
case cond
when ‘thing1’
…do thing1 stuff…
when ‘thing2’
…do thing2 stuff…
cond = ‘thing1’
casefunc.call(cond)
end
}
casefunc.call(cond)

···

On Thu, Sep 05, 2002 at 09:56:55AM +0900, Dan Debertin wrote:

I was reminded of this problem by the recent ‘breaking out of case’
thread. I have a ‘case’ statement that evaluates a condition:

case cond
when ‘thing1’
…do thing1 stuff…
when ‘thing2’
…do thing2 stuff…
cond = ‘thing1’
end


Alan Chen
Digikata LLC
http://digikata.com

Abstract the desired behavior into methods or functions of their own:

def restartable
yield
end

restartable do
case cond

when ‘thing2’
…do thing2 stuff…
cond = ‘thing1’
redo
end
end

Note that using ‘redo’ is not necessary. We can go with catch & throw,
and define a ‘restart’ function instead, and then we can also do it from
inside blocks:

def restartable
done = false
until done do
catch (:restart) do
yield
done = true
end
end
end

def restart
throw :restart
end

restartable do
case cond

when ‘thing2’
…do thing2 stuff…
cond = ‘thing1’
array.each {|x| restart if x == foo}
end
end

This approach can of course be generalized to all sorts of behaviors.

[…]

		Reimer Behrends
···

Dan Debertin (airboss@nodewarrior.org) wrote:

I was reminded of this problem by the recent ‘breaking out of case’
thread. I have a ‘case’ statement that evaluates a condition:

case cond
when ‘thing1’
…do thing1 stuff…
when ‘thing2’
…do thing2 stuff…
cond = ‘thing1’
end

The ‘thing2’ clause changes the value of ‘cond’, so I want to be able
to bounce back to the top and re-evaluate the case. The way I ended up
doing it was: