понедельник, 27 мая 2013 г.

Еще немного о контексте и блоках

Написанное мною в предыдущем посте можно понять так, что “define_method”, а точнее — блок вообще, не формирует своего контекста и области видимости локальных переменных. Это не совсем так — блок формирует собственный контекст, но этот контекст не является изолированным, в отличие от контекста, определенного “def”.

Рассмотрим пример:

$DATA = [
  {
   :name => :alpha,
   :value => "A"
  },
  {
   :name => :beta,
   :value => "B"
  }
]

def plus obj
  # value = nil
  $DATA.each do |item|
    value = item[:value]
    obj.define_singleton_method item[:name] do
      p value
    end
  end
end

a = Object.new
plus a

a.alpha
a.beta

Выполнив его, мы получим ожидаемый результат:

"A"
"B"

Это означает, что переменная “value” является локальной в блоке при “each” и не сохраняется между итерациями. Если же мы раскоментируем строчку “value = nil” над блоком, та же переменная будет уже относиться к другому контексту и результатом запуска станет:

"B"
"B"

И такая мелочь вполне может вылиться в лишние часы отладки...

Комментариев нет:

Отправить комментарий