赢得自定义新的遗物弹球机!只需将数据书呆子提交以注册Futureestack。 立即注册

这是关于Weird Ruby系列的第1部分。不要错过奇怪的Ruby第2部分:卓越的保障奇怪的红宝石第三部分:有趣的人字拖,奇怪的Ruby第4部分:代码荚(块、过程和lambda)

这是我最近发言的一系列帖子中的第一个帖子保持Ruby奇怪德克萨斯州奥斯汀会议。我一直在使用Ruby全职了解了几年,并看到了很多事情,让我划伤了我的头脑。由于我已经更多地了解这类语言,因此一些设计决策的原因已经变得更加清晰,我想分享一些角度。

让Ruby奇怪本系列介绍了Ruby的一些不寻常的、可能违反直觉的行为,特别是那些让新开发人员或其他语言的新手感到惊讶的行为。它并不是另一个“WTF Ruby?!”的代码示例。相反,我希望对这些行为以及它们的实际原因提出另一种观点重要的我们如何使用语言。

进入开始结束块,一个看似无害的控制结构,通常对代码没有太大影响。结合救援它可以收集和处理错误,如果我们添加一个别的为了补救,我们可以在没有看到错误的情况下运行代码。Begin-end块也可以与' ensure '块一起使用,以确保一些代码能够运行。当你把它们和条件句结合起来的时候…意想不到的事情开始发生。让我们从一开始就开始。

将花键网纹键入

在孤独的开始端块中的开始并不真正开始任何内容,最终实际上也不结束任何内容。单独的Begin-End块中的包装代码根本不会改变代码的行为,它本身就很奇怪。

看看这个例子:

@splines.reticulate

我们有一些需要象限的样条,因为他们经常这样做,我们将在开始结束的块中包装它们,看看有哪些变化:

开始@ vetpines.trefulate结束

这些示例中的代码的所有行为都是相同的。返回值是相同的,生成的字节码也几乎完全相同。

我们如何知道这一点?你可以使用一个RubyVM: InstructionSequence偷看百姓窥视你的红宝石。这是我们网状样条的字节码示例:

没有起止:

0000 trace 1 (1) 0002 getinstancevvariable:@splines, 0005 opt_send_simple  0007离开

起止:

0000跟踪1(1)0002跟踪1 0004 GetInstanceVariable:@Splines,0007 Opt_Send_Simple  0009离开

Ruby使用基于堆栈的虚拟机(VM),所以值被推到堆栈上,然后每次取出一个值来作用于下一个值,直到我们到达开始状态并返回结果。

第一个指令是跟踪,我们等下会讲到。第二条指令是getinstancevariable: @splines,这将是关于您所期待的:它将获得价值@Splines.。下一个opt_send_simple.线发送网状消息@Splines.最后的休假指令告诉我们,我们都结束了。

我们之前跳过的跟踪指令才能启用Ruby的TracePoint功能。您可以使用TraCepopoint在程序中为每个语句运行一些代码。请注意,第二个开始最终示例实际上具有额外的跟踪指令;该跟踪是用于开始结束块的。trapopoint功能很有趣,请看看的文档和玩耍。只要记住不要在生产中做这种事情,它会大大降低应用程序的速度。

花键会网?

我认为我们已经很好地确定了begin-end块本身并没有多大作用,所以让我们看看当我们将它们与一些条件语句一起使用时会发生什么。是时候问“它会形成网状结构吗?”的游戏:

@拼接。如果是假的

它会网?绝对没有,那些花键在水中死了,我们的船可能因为它而崩溃。如果条件函数完全相同,那么它将是它的。

怎么样?

开始@ vetpines.trefulate结束if false

没有?你是正确的。如果我们不快点联系我们就死定了。让我们看看这是否会网状:

@splines.reticulatewhile false

不幸的是没有。好吧,如果那不起作用,当然这个也不会起作用:

beart @ vetpines.Reticulate结尾而False

惊讶!这实际上将标识我们的样条纹。只是一次,但每个人都知道一次足够好的样条曲线。

在这里,我们偶然发现了Ruby的做的建筑,呢开始结束循环。这是一个后置条件循环:它仅在处理循环的主体后检查循环条件。上面的代码将为样条旋转一次,然后检查布尔后状态并确定它不应再旋转。

通常情况下,这种begin-end-while循环会让偶然发现它的倒霉开发人员感到惊讶,因为begin-end块本身通常不会改变行为(正如我们前面所看到的)。Matz.他自己曾说过他对Ruby中的这种行为感到遗憾,他更希望开发人员使用类似于这一点相反:

循环做@splines。网状break if true end

建议的环路破坏构造的效果完全相同:我们将始终将样条纹标记一次。唯一的区别是循环代码不太可能混淆。

奇怪的收入

很快就会在更奇怪的Ruby中调整,我们会看一些其他可能意外的行为:你的可能性确保块实际上不会确保任何东西。

Ruby的形象由shutterstock.com提供。