如果您希望报告此常见问题解答中的错误或提出改进建议,请访问我们的 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
如何使用延续?
本节或其部分内容可能已过时或需要确认。
Ruby 的延续允许您创建一个表示 Ruby 程序中某个位置的对象,然后随时返回到该位置(即使它显然已超出范围)。延续可用于实现复杂的控制结构,但通常更适合用来迷惑人们。
在 [ruby-talk:4482] 中,Jim Weirich 发布了以下延续示例
# --------------------------------------------------------------------
# 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