Официальный FAQ по Ruby
If you wish to report errors or suggest improvements for this FAQ, please go to our GitHub repository and open an issue or pull request.
Другие возможности
Что означает a ? b : c?
Это так называемый «тернарный оператор», и он эквивалентен записи if a then b else c end.
Как я могу подсчитать количество строк в файле?
Следующий код может дать самый быстрый результат.
File.readlines("example").size # => 3
Что возвращают MatchData#begin и MatchData#end?
Они работают с $~ и возвращают начальный и конечный индексы совпавших данных в исходной строке. Смотрите пример в разделе развертывание табуляции.
Как я могу просуммировать элементы массива?
This section or parts of it might be out-dated or in need of confirmation.
Вместо решения конкретной задачи, давайте решим её в общем виде. Первое, что мы сделаем — создадим метод, который будет итерироваться по объекту 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
Как я могу использовать продолжения (continuations)?
This section or parts of it might be out-dated or in need of confirmation.
Продолжения (continuations) в 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