From: Luke Graham Date: 2005-02-14T17:34:19+09:00 Subject: Re: can anyone verify this code as correct? On Mon, 14 Feb 2005 17:07:00 +0900, E S wrote: > > L�hett�j�: Luke Graham > > Aihe: can anyone verify this code as correct? > > > > class Object > > def choices(choicelist) > > if (!Class.class_variables.include? "@@cont") > > @@cont = [] > > end > > You can use '@@cont ||= []'. Thanks, I like that one. > > choicelist.each { |choice| > > callcc { |cc| > > @@cont << cc > > return choice > > } > > } > > nil > > end > > Continuation returns after the block, either with the value of the > block or the parameter to #call, and it stores its execution context. > Here you're returning in the middle of a loop, so I'm thinking each > #call will cause the remaining 'choicelist' to be iterated over again, > so the actual return value is going to be 'choicelist'. I dont understand... the return value is definitely not choicelist, but a different choice each time. The callcc is -inside- the internal iteration. After all values have been exhausted, nil is the last thing to be returned, and effectively marks the limit of choices, as '\0' does for c-strings. The array could probably stand to be flattened first, just in case. > > def condition(cond) > > return if (self.class == NilClass?) > > @@cont.pop.call if !cond.call > > end > > end > > You're attempting to loop until the condition is true? If I'm > understanding correctly you're trying to find the first values that > fill all the conditions set forth? Yes, or nil if there are no such values. > > class NilClass? > > def method_missing(methId, *args) > > return false > > end > > end > > > > > > foo = choices(1..100) > > bar = choices(1..100) > > choices() returns nil, no? If all choices are exhausted, it does eventually return nil. However, in the case of bar, it will once again start returning from the beginning of the array if foo is unacceptable. Of course, we dont really know if that value of foo is unacceptable or if its just that all possible values of bar are unacceptable - that can only be determined by more computation. > > condition(lambda{foo == (bar * 3)}) > > condition(lambda{bar > 10}) > > condition(lambda{(bar % 2) == 0}) > > puts foo > > puts bar > > > > Thanks for your help. > > What are you trying to do, exactly? I'm sure there's an easier way if > you just want to compose conditionals like this; or are you trying to > get a handle on how callcc works? In the former case, you'd probably > want to try something with blocks instead... callcc is really just a > glorified goto. > > E Im just hacking around to see what sort of valid flow control constructs exist apart from the regular loops and such. The major problem Ive seen so far with what I have is adding a further set of choices after the originals, and before the conditions, adds exponentially to the time required. To be honest, that doesnt worry me because Im just having fun.