如何创建自定义块

Gio*_*ssi 5 ruby

我知道在ruby中我们可以使用while循环,但我想知道我是否可以创建一个自定义的循环,所以我可以做这样的事情:

custom_while i < 5 do
    puts i
    i += 1
end
Run Code Online (Sandbox Code Playgroud)

我目前有这个代码:

def custom_while(condition)
    loop do
        break if not condition
        yield
    end
end

i = 0
custom_while i < 5 do
    puts i
    i += 1
end
Run Code Online (Sandbox Code Playgroud)

但是,在condition评估时,它总是变为真(因为它只考虑第一次评估i < 5 = true.

任何帮助将不胜感激!

注意:这仅用于教育目的.

Jör*_*tag 4

你几乎已经拥有了。那么,您的问题是条件仅评估一次?那么,我们知道什么构造可以根据需要多次评估呢?没错:函数!那么,让我们创建condition一个函数(或者ProcRuby 术语中的 a):

def custom_while(condition)
  loop do
    break unless condition.()
    yield
  end
end

i = 0
custom_while -> { i < 5 } do
  puts i
  i += 1
end
# 0
# 1
# 2
# 3
# 4
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不像其他语言那样好看。Ruby 的语法和语义针对仅采用 1 个“函数”作为参数的方法进行了积极优化。Ruby 有一个特殊的语法和语义轻量级结构,即块。然而,一旦你拥有多个,你就倒霉了。

将此与具有适当块文字的语言(例如 Smalltalk)进行比较。在 Smalltalk 中,您可以编写一个方法while:do:,并像这样调用它:

i := 0.
while: [i < 5] do: [Transcript write: i. i := i + 1].
Run Code Online (Sandbox Code Playgroud)

事实上,在 Smalltalk 中,块的语法非常轻量级,以至于该语言中根本没有控制结构。if//then只是else一个实例方法Boolean,例如:

i % 2 == 0 ifTrue: [Transcript write: "even"] ifFalse: [Transcript write: "odd"].
Run Code Online (Sandbox Code Playgroud)

Andwhile实际上是 的实例方法Block,所以实际上,您的示例将如下所示:

i := 0.
[i < 5] whileTrue: [Transcript write: i. i := i + 1]
Run Code Online (Sandbox Code Playgroud)

注意:我对 Smalltalk 代码不做任何保证,我没有测试它。