Ruby .times 方法调用一个整数。它如何知道将每个整数作为 block 中的参数进行迭代?

标签 ruby

我正在阅读 "Pickaxe" ruby book我遇到了这个例子:

def meth_three
  100.times do |num|
    square = num*num
    return num, square if square > 1000
  end
end

如果您在 irb 中调用 meth_three,它会返回 1 到 100 之间第一个具有 square > 1000 的整数:

meth_three # => [32, 1024]

我的问题是,times 方法如何知道如何遍历 1..100 之间的每个整数以作为参数传递给 |num| 参数?

最佳答案

在 Ruby 中有许多不同的迭代方式。

这是递归实现的一种可能方式:

class Integer
  def times(&blk)
    return enum_for(__callee__) unless block_given?
    return self unless positive?

    pred.times(&blk)

    yield pred
  end
end

或者,使用 Range#each:

class Integer
  def times(&blk)
    return enum_for(__callee__) unless block_given?
    return self unless positive?

    (0...self).each(&blk)

    self
  end
end

或者,用一个循环:

class Integer
  def times
    return enum_for(__callee__) unless block_given?
    return self unless positive?

    i = -1
    yield i while (i += 1) < self

    self
  end
end

还有一个尾递归实现,只是为了好玩:

class Integer
  def times(&blk)
    return enum_for(__callee__) unless block_given?
    return self unless positive?

    __times_rec(0, &blk)

    self
  end

  private def __times_rec(i, &blk)
    return unless i < self

    yield i

    __times_rec(i.succ, &blk)
  end
end

这是实际 Ruby 实现的实际代码(core/integer.rb 来自Rubinius):

def times
 return to_enum(:times) { self } unless block_given?

 i = 0
   while i < self
     yield i
     i += 1
   end
 self
end

TruffleRuby也使用完全相同的代码(参见 src/main/ruby/truffleruby/core/integer.rb ), JRuby 也是如此(参见 core/src/main/ruby/jruby/ruby_implementations/Integer/times.rb)

这是来自真实 Ruby 实现的另一个真实示例(opal/corelib/number.rb 来自 Opal):

def times(&block)
 return enum_for(:times) { self } unless block

 %x{
   for (var i = 0; i < self; i++) {
     block(i);
   }
 }

 self
end

如您所见,可以通过多种方式在 Ruby 中编写循环。

关于Ruby .times 方法调用一个整数。它如何知道将每个整数作为 block 中的参数进行迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63018797/

相关文章:

ruby - 为什么我收到 unsupportedSchemeError

ruby-on-rails - 如何在 Ruby 中处理包含空格的文件名(在 Git Bash 中)

ruby-on-rails - 自动删除 Amazon S3 中超过 n 天的对象(如何?)

java - 相当于 Ruby :symbol in Java?

ruby - 如何使用 HAML 遍历数组?

ruby-on-rails - Ruby on Rails 取消首字母大写

ruby-on-rails - Rails 6 期望文件定义常量

ruby - 在此 Ruby 示例中如何限制重试和救援?

ruby - 使用 ruby​​ 和 aws-sdk 拉取 ec2 标签

ruby - 如何模拟aws-sdk gem?