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
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: