【问题标题】:Ruby Shoes4 : how does Sample13 work?Ruby Shoes4:Sample13 是如何工作的?
【发布时间】:2013-07-23 22:00:57
【问题描述】:

我最近重新发现了 Ruby Shoes 框架,这是一个小型图形框架,使用 Ruby 内部 DSL 功能,更具体地说,这里是 Shoes4

其中一个示例(位于 ./samples 中)给我留下了特别深刻的印象:sample13.rb,我无法完全理解。

运行此示例,您将获得一个带有名为“new”的按钮的画布。每次按下此按钮时,都会将一个新图形(在程序中命名为框)添加到画布(形状和颜色随机)。但更重要的是,您可以在之后单击这些数字,然后将它们移开。

代码非常短:

Shoes.app :width => 300, :height => 300 do
  COLORS = Shoes::COLORS
  i = 45

  button 'new' do
    i += 5
    box = rand(2) == 0 ? rect(i, i, 20) : oval(i, i, 20)
    box.style :fill => send(COLORS.keys[rand(COLORS.keys.size)])
    @flag = false
    box.click{@flag = true; @box = box}
    box.release{@flag = false}
  end

  motion{|left, top| @box.move(left-10, top-10) if @flag}
end

我想了解一下这段代码的工作原理。

似乎创建的每个图形都存储在某个地方,但具体在哪里?有没有办法访问新创建的人物集合?

此外,如图所示,还添加了clickrelease等方法。一般来说,鞋子中的每个对象都是这种情况吗(我在鞋子网站上找不到)?

【问题讨论】:

    标签: ruby jruby shoes


    【解决方案1】:

    所以这些数字没有存储在任何地方,但有相当多的范围魔法正在发生。 click 和 release 元素在相当多的元素上可用,应该是提到的所有元素 here under :click 但该列表在 Shoes4 中尚不完全支持。

    那么让我们一一来看:

    box.click{@flag = true; @box = box}
    box.release{@flag = false}
    

    所以当一个元素被点击时,@flag 被设置为 true(该标志似乎标志着一个元素当前正在被拖动),这就是为什么当释放鼠标点击时该标志被设置为 false。此外,单击时会发生实例变量@box 设置为刚刚单击的框。这是可能的,因为块保留了它们在其中创建的范围。这意味着范围会记住box 指的是单击框时调用的块的创建框。这是可能的,因为在创建块期间将引用保存在局部变量box 中,并且块捕获了这个范围。

    现在开始议案:

    motion{|left, top| @box.move(left-10, top-10) if @flag}
    

    Motion 捕捉鼠标的移动。它的作用是将当前单击的框(如果有,则为@flag)移动到当前鼠标光标的位置(由顶部和左侧指定)。我不知道为什么需要 -10,但我似乎记得我们在其他地方遇到了问题。我会尝试调查并打开问题,但这在这里并不重要:-)

    哦,感谢您试鞋! :-) 另外感谢您告诉我您实际上可以拖动它们,我什至不知道!

    【讨论】:

    • 好的。重要的部分是关于范围机制的,目前还不清楚,所以我不想验证你的答案。
    • 我只是尝试扩展块的范围。这能解释吗?如果没有 - 什么还不清楚?
    • 我还是没明白。在执行期间,局部变量(如框)被删除,在块的末尾,没有?所以通常(据我了解Ruby),只有最后一个受@box(实例)影响的盒子可以被移动(在“运动”方法中)。
    • 不,它们没有被删除。仍然有一些对它们的引用(比如鞋子内部),这就是为什么 Ruby 垃圾收集器不会杀死它们的原因。因此,这些对象仍然存在,并且仍然添加了该单击处理程序,以便您可以单击它们。
    猜你喜欢
    • 1970-01-01
    • 2012-11-29
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2017-07-17
    • 2011-02-17
    相关资源
    最近更新 更多