Как работает метод title внутри блока TkRoot в Ruby? - PullRequest
1 голос
/ 13 мая 2019

Я знаю, что это странный вопрос. Но я ломал голову, размышляя о том, как метод с названием title определяется внутри TkRoot.new { title('Something') }

Хорошо, вот пример кода:

#!/usr/bin/ruby
require 'tk'

p defined?(title)    # => nil
root = TkRoot.new { p defined?(title) } # writes "method" to stdout.

Вот ссылка на официальное руководство

Я изучил исходный код, который кажется очень запутанным (и, возможно, заполнен всеми плохими методами, которые затрудняют чтение кода) и заполнен предупреждениями, когда все предупреждения включены.

У меня вопрос, как определение метода работает только внутри блока? Могу ли я получить небольшой пример кода, который показывает, как ограничить определение метода только блоком?

1 Ответ

4 голосов
/ 13 мая 2019

Ключом к этой черной магии является instance_eval, который оценит блок в контексте его получателя.Обычно self внутри блока будет определяться областью действия;instance_eval изменит self внутри своего блока на то, что получило сообщение instance_eval.

class Dog
  def bark
    puts "Woof"
  end

  def initialize(&block)
    instance_eval(&block)
  end
end

Dog.new { bark }
# => "Woof"

В этом случае instance_eval(&block) совпадает с self.instance_eval(&block), что означает self внутри блока будет экземпляр Dog;тогда bark - это, конечно, self.bark, где self - это Dog.

Существует школа мысли, что instance_eval является вредным .Я согласен, что лучше всего ограничить его использование четко определенными DSL.То есть это может работать для TK, RSpec или Sinatra, но если вы думаете, что это круто и хотите использовать его, хорошо подумать дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...