Skip to content

Instantly share code, notes, and snippets.

@yesnik
Created December 24, 2014 06:56
Show Gist options
  • Save yesnik/0ab880b484e44b69ebbe to your computer and use it in GitHub Desktop.
Save yesnik/0ab880b484e44b69ebbe to your computer and use it in GitHub Desktop.
Задание по Ruby 2
# Пример 1
def m
a = 1
lambda { a + 1 }
end
f = m
a = 3
f.call #=> ?
# Пример 2
def n
b = 1
Proc.new { b + 1 }
end
b = 10
n.call #=> ?
# Пример 3
module M1
def a
1
end
end
module M2
def a
2
end
end
class A
extend M1
extend M2
include M1
include M2
def a
super + 5
end
end
p A.a #=> ?
a = A.new
p a.a #=> ?
@yesnik
Copy link
Author

yesnik commented Dec 24, 2014

Пример 1. Ответ: 2.
Вызов метода m вернет нам лямбда-функцию, которую мы вызываем посредством .call. Ламбда-функция получает доступ к переменным области видимости, в которой она вызвана. В этом случае это переменная a = 1.
Если в методе m переменную a не определить, то возникнет ошибка:

def m
  lambda { a + 1 }
end
a = 10
m.call
#=> NameError: undefined local variable or method `a' for main:Object

Пример 2. Ответ: 2.
Proc, подобно лямбда-функциям, тоже выполняется в контексте вызова, поэтому на момент его вызова он будет "знать", что b = 1. Аналогично, если из определения функции n убрать запись b = 1, то при попытке вызова n.call возникнет NameError:

def n
  Proc.new { b + 1 }
end
b = 5
n.call
#=> NameError: undefined local variable or method `b' for main:Object

Пример 3. Ответ: A.a вернет 2, a.a вернет 7.

  1. extend добавляет методы к классу, а не к его объекту. Поскольку сначала был extend M1, затем M2, поэтому цепочка наследования выглядит так: A < M2 < M1. Следовательно, при вызове A.a метод a будет сначала искаться в классе A (его там нет), затем в M2 (он там есть, именно он вернет 2).
  2. include добавляет методы к объекту класса, а не самому классу. Сначала был include M1, затем M2, поэтому цепочка наследования такая: a < M2 < M1. При вызове a.a метод "a" ищется в объекте a, и он там присутствует.
    Однако в этом методе используется слово super, что говорит о необходимости вызова метода "a" родительского объекта. Это будет метод "a" модуля M2, который вернет 2. 2 + 5 = 7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment