内容 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

官方 Ruby FAQ

如果您希望报告错误或对本 FAQ 提出改进建议,请访问我们的 GitHub 仓库,并提出 issue 或 pull request。

其他功能

a ? b : c”是什么意思?

这是所谓的“三元运算符”,等同于说“if a then b else c end”。

如何计算文件中的行数?

以下代码可能提供最快的速度。

File.readlines("example").size  # => 3

MatchData#beginMatchData#end 返回什么?

它们与$~一起工作,返回原始字符串中匹配数据的起始索引和结束索引。有关示例,请参阅标签扩展

如何对数组中的元素求和?

本节或部分内容可能已过时或需要确认。

与其解决具体问题,不如解决一般情况。我们将做的第一件事是创建一个方法,该方法可以迭代Enumerable对象并收集单个结果。Smalltalk 将该方法称为 inject,所以我们也这样做。

module Enumerable

  # inject(n) {|n, i| ...}
  def inject(n)
    each {|i| n = yield(n, i) }

    n
  end
end

注意我们是如何将该方法添加到Enumerable的。这意味着任何包含 Enumerable 的东西现在都可以使用 inject。但我们如何使用它呢?它接受一个参数 n 和一个块。对于正在枚举的事物的每个元素,它会调用该块,并将 n 和元素本身传递进去。该块的结果被重新赋值给 n。因此,要定义 sum,我们可以编写:

module Enumerable
  def sum
    inject(0) {|n, i| n + i }
  end
end

[1,3,5,7,9].sum  # => 25
(1..100).sum     # => 5050

如何使用 continuation?

本节或部分内容可能已过时或需要确认。

Ruby 的 continuation 允许您创建一个表示 Ruby 程序中某个位置的对象,然后随时返回到该位置(即使它似乎已超出范围)。Continuation 可用于实现复杂的控制结构,但通常更适合用来混淆他人。

[ruby-talk:4482]中,Jim Weirich 发布了以下 continuation 示例:

# --------------------------------------------------------------------
# Simple Producer/Consumer
# --------------------------------------------------------------------
# Connect a simple counting task and a printing task together using
# continuations.
#
# Usage:  count(limit)

def count_task(count, consumer)
  (1..count).each do |i|
    callcc {|cc| consumer.call cc, i }
  end
  nil
end

def print_task()
  producer, i = callcc { |cc| return cc }
  print "#{i} "
  callcc { |cc| producer.call }
end

def count(limit)
  count_task(limit, print_task())
  print "\n"
end
# --------------------------------------------------------------------
# Filtering Out Multiples of a Given Number
# --------------------------------------------------------------------
# Create a filter that is both a consumer and producer. Insert it
# between the counting task and the printing task.
#
# Usage:  omit(2, limit)

def filter_task(factor, consumer)
  producer, i = callcc { |cc| return cc }
  if (i%factor) != 0 then
    callcc { |cc| consumer.call cc, i }
  end
  producer.call
end

def omit(factor, limit)
  printer = print_task()
  filter = filter_task(factor, printer)
  count_task(limit, filter)
  print "\n"
end
# --------------------------------------------------------------------
# Prime Number Generator
# --------------------------------------------------------------------
# Create a prime number generator. When a new prime number is
# discovered, dynamically add a new multiple filter to the chain of
# producers and consumers.
#
# Usage:  primes(limit)

def prime_task(consumer)
  producer, i = callcc { |cc| return cc }
  if i >= 2 then
    callcc { |cc| consumer.call cc, i }
    consumer = filter_task(i, consumer)
  end
  producer.call
end

def primes(limit)
  printer = print_task()
  primes = prime_task(printer)
  count_task(limit, primes)
  print "\n"
end