Ruby глобальная область - PullRequest
6 голосов
/ 28 марта 2012

Отвечая на другой вопрос, я понял, что следующая программа не совсем делает то, что, как я думал, делает.

puts "test"
self.puts "test"  # => private method `puts' called for main:Object (NoMethodError)

Исключение удивляет меня, поскольку я всегда думал, что вызовы методов верхнего уровня будутразрешается экземпляром объекта main, но это не так.

Кто является фактическим получателем первого вызова и как он разрешается?Это специальное правило, которое применяется только к вызовам методов в области верхнего уровня?

1 Ответ

5 голосов
/ 28 марта 2012

Вот хорошее обсуждение , в котором говорится об этом вопросе.

Методы верхнего уровня, предоставляемые Kernel , автоматически включаются в Объект класс.Это означает, что методы ядра появятся во всем.

Ошибка private method 'puts' called for main:Object (NoMethodError) просто говорит о том, что put существует, но имеет частную область действия.

ree-1.8.7-2011.03 :001 > puts "test"
test
ree-1.8.7-2011.03 :004 > self.send(:puts, "hi" )
hi

ОБНОВЛЕНИЕ

В ядре нет магииметоды.Там нет прыгающего прицела или чего-то еще.Я думаю, что путаница в том, какова область применения self.У вас нет доступа к закрытым методам с помощью self.

class PutsTest

  def success_puts
    private_puts
  end

  def failed_puts
    # trying to access a private method from self
    self.private_puts
  end

  private

  def private_puts
   puts 'hi'
  end
end

Используя self , вы изменяете область действия, не вызывая метод внутри PutsTest на звонки извне PutsTest

ree-1.8.7-2011.03 :095 > test = PutsTest.new
ree-1.8.7-2011.03 :096 > test.success_puts
hi
ree-1.8.7-2011.03 :097 > test.failed_puts
NoMethodError: private method `private_puts' called for #<PutsTest:0xd62c48>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...