2013-03-28 53 views
1

对不起,如果我不以正确的方式问我的问题。Ruby Enumerable和Yield的使用情况

试图让这一点的Ruby代码工作。我不明白的是如何让底部的点击操作调用yield函数(这是一个交通灯),以便点击将循环访问yield选项。真实的,错误的,错误的将意味着光是红色的,因为它在顶部,而底部的是错误的。我也很难在统计员和收益率之间缠绕我的头脑。

class TrafficLight 
    include Enumerable 
    include TL 

    def each 
    yield [true, false, false] 
    yield [true, true, false] 
    yield [false, false, true] 
    yield [false, true, false] 
    end 
end 

class Bulb < Shoes::Shape 
    attr_accessor :stack 
    attr_accessor :left 
    attr_accessor :top 
    attr_accessor :switched_on 

    def initialize(stack, left, top, switched_on = false)  
    self.stack = stack #don't change. 
    self.left = left  
    self.top = top 
    self.switched_on = switched_on 
    draw left, top, bulb_colour 

    end 

    # HINT: Shouldn't need to change this method 
    def draw(left, top, colour 
    )  
    stack.app do 
     fill colour 

     stack.append do 
     oval left, top, 50 
     end 
    end 
    end 

    def bulb_colour 
    "#999999" 
    end 
end 

class GoBulb < Bulb 
    def bulb_colour 
    "#00FF30" 
    end 
end 

class WaitBulb < Bulb 
    def bulb_colour 
    "#FFFC00" 
    end 
end 

class StopBulb < Bulb 
    def bulb_colour 
    "#FF0000" 
    end 
end 

module TL 
    Go = "#00FF30" 
    Wait = "#FFFC00" 
    Stop = "#FF0000" 
end 

Shoes.app :title => "My Amazing Traffic Light", :width => 150, :height => 250 do 
    background "000", :curve => 10, :margin => 25 
    stroke black  

    @traffic_light = TrafficLight.new 
    @top = StopBulb.new self, 50, 40, true  
    @middle = Bulb.new self, 50, 100, true 
    @bottom = Bulb.new self, 50, 160, true 


    click do #make this switch on/off depending on what you click. Only 1 should be on 

    end 
end 

我GOOGLE了搜查,但枚举的例子我没有让我做什么,我需要做的。任何见解都非常感谢。

+0

你需要循环中的枚举(即,它应该回到红黄色之后)? – 2013-03-28 11:29:29

+0

嗨,欢迎来到堆栈溢出。我认为你的问题可以说得更好。试着弄清楚你的问题是什么。此外,你有复制/粘贴了很多代码。如果将其减少到仅仅是为了使问题真正需要的线条,人们将更有可能花时间阅读它。 – 2013-03-28 11:49:29

回答

2

装有当前版本Shoes的Ruby(1.9.1)在Enumerator#next上有一些意外的行为。当这个方法被调用时它会卡住。所以你不能迭代检索Enumerator的值。

TrafficLight类必须重新编写以模仿Enumerator#next。如果在next上没有这样的错误,我们可以使用TraficLight.new.cycle并在该循环枚举器上反复调用next。

module TL 
    Go = "#00FF30" 
    Wait = "#FFFC00" 
    Stop = "#FF0000" 
end 

class TrafficLight 
    include TL 
    STATUS = [ 
    [true, false, false], 
    [true, true, false], 
    [false, false, true], 
    [false, true, false] 
    ] 
    def initialize; @index = 0; end 
    def current 
    STATUS[@index % STATUS.size] 
    end 
    def next 
    @index += 1 
    current 
    end 
end 

更新Bulb,添加一个方法update(on)重绘灯泡。

def update(on = false) 
    self.switched_on = on 
    draw self.left, self.top, on ? self.bulb_colour : '#999999' 
end 

和更新Shoes.app主要逻辑使用特定的灯泡:

@traffic_light = TrafficLight.new 
@top = StopBulb.new self, 50, 40, true  
@middle = WaitBulb.new self, 50, 100, false 
@bottom = GoBulb.new self, 50, 160, false 

click do #make this switch on/off depending on what you click. Only 1 should be on 
    status = @traffic_light.next 
    [@top, @middle, @bottom].zip(status).each do |light, on| 
    light.update(on) 
    end 
end