官方 Ruby FAQ
如果您希望报告错误或对本 FAQ 提出改进建议,请访问我们的 GitHub 仓库,并提出 issue 或 pull request。
其他功能
“a ? b : c”是什么意思?
这是所谓的“三元运算符”,等同于说“if a then b else c end”。
如何计算文件中的行数?
以下代码可能提供最快的速度。
File.readlines("example").size # => 3
MatchData#begin 和 MatchData#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