Мы имеем:
def fib (n)
return n if n <= 1
fib(n - 1) + fib(n - 2)
end
, который вы понимаете. Во-первых, давайте посмотрим, что первые 5 чисел Фибоначчи ::
fib_array = []
5.times do |x|
fib_array << fib(x)
end
fib_array
#=> [0, 1, 1, 2, 3]
Теперь давайте разберем это вниз и посмотреть, что происходит. Сначала просмотрите документы для метода times
. Чтобы найти их, нам нужно знать, из какого класса или модуля этот метод, потому что так организованы документы. Как 5.class #=> Fixnum
, мы можем посмотреть документы для Fixnum. Хммм. times
нет. По-видимому, он был унаследован от другого класса.Давайте проверим:
Fixnum.ancestors
#=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
Integer
включает Fixnum
и BigNum
, Numeric
включает Integer
и Float
. (3.14).times
не имеет смысла, поэтому появляется times
определяется в Integer
, и так есть: Integer#times. Определив его, он наследуется как Fixnum
, так и Bignum
.
Вот прямой способ, чтобы определить, где метод пришел из:
5.method(:times).owner #=> Integer
Это не важно понять это сейчас, но вы найдете его под рукой, как вы получаете опыт работы с Ruby.
ОК, документы говорят, что times
возвращает значение, если задано блок, или перечислитель, если нет. Давайте забудем о блоке момент и посмотреть на счетчику, который возвращается:
enum = 5.times #=> #<Enumerator: 5:times>
Метод Enumerator#each передает элементы счетчику enum
к его блоку:
do |x|
fib_array << fib(x)
end
назначая их к переменной блока x
. Чтобы увидеть содержимое счетчику, преобразовать его в массив:
enum.to_a #=> [0, 1, 2, 3, 4]
Результат:
fib_array = []
enum.each do |x|
fib_array << fib(x)
end
fib_array
#=> [0, 1, 1, 2, 3]
, который, конечно, тот же самый результат, который мы получили ранее. Теперь давайте посмотрим, что происходит шаг за помощью, с помощью метода Enumerator#next для извлечения каждого элемента счетчику:
x = enum.next #=> 0
fib(x) #=> 0
fib_array << fib(x) #=> [0]
x = enum.next #=> 1
fib(x) #=> 1
fib_array << fib(x) #=> [0, 1]
x = enum.next #=> 2
fib(x) #=> 1
fib_array << fib(x) #=> [0, 1, 1]
x = enum.next #=> 3
fib(x) #=> 2
fib_array << fib(x) #=> [0, 1, 1, 2]
x = enum.next #=> 4
fib(x) #=> 3
fib_array << fib(x) #=> [0, 1, 1, 2, 3]
print fib_array # [0, 1, 1, 2, 3]
Это все есть на него.