Что на самом деле происходит, когда в Ruby указывается «private» / «protected» - PullRequest
6 голосов
/ 06 ноября 2011

Что на самом деле происходит, когда private / protected указано в определении класса Ruby? Они не являются ключевыми словами , поэтому подразумевается, что они должны быть вызовами методов, но я не могу найти, где они определены. Они, кажется, не документированы. Два разных способа объявления private / protected методов (показанных ниже) реализованы по-разному? (Второй способ, очевидно, является вызовом метода, но в первом случае это не так очевидно.)

class Foo
  private
  def i_am_private; end
  def so_am_i; end
end

class Foo
  def i_am_private; end
  def so_am_i; end
  private :i_am_private, :so_am_i
end

Ответы [ 2 ]

9 голосов
/ 06 ноября 2011

Оба являются вызовами методов. Цитирование из документов :

Каждая функция может использоваться двумя различными способами.

  1. Если используется без аргументов, три функции устанавливают контроль доступа по умолчанию для определенных впоследствии методов.
  2. С аргументами функции устанавливают управление доступом для именованных методов и констант.

См. Документацию здесь:

  1. Module.private
  2. Контроль доступа

Вы искали, как появляется метод Module.private. Вот где это происходит . И вот еще немного информации об этом. Вы должны были бы прочитать больше об этом, начиная с rb_define_private_method, определенного в class.c.

Надеюсь, это поможет!

0 голосов
/ 02 мая 2012

Я хотел бы добавить что-нибудь об их подобном ключевому слову поведении , потому что ответы были больше о , где , чем как ; Ответ заключается в сложных метапрограммирующих возможностях Ruby. Их можно использовать как ключевые слова , используя хук method_added; ловушка в Ruby - это функция, которая вызывается, когда происходит определенное событие (то есть имя ловушки). Важно то, что хук method_added получает в качестве аргумента имя метода, который был определен: таким образом, можно изменить его поведение.

Например, вы можете использовать этот хук, чтобы определить поведение, подобное декораторам Python ; важная часть состоит в том, что, в отличие от методов private и protected, этот подобный декоратору метод должен определять method_added, который определяет себя сам:

class Module
  def simple_decorator
    eigenclass = class << self; self; end
    eigenclass.class_eval do
      define_method :method_added do |name|
        eigenclass.class_eval { remove_method :method_added }
        old_name = 'old_' + name.to_s
        alias_method old_name, name
        class_eval %Q{
          def #{name}(*args, &block)
            p 'Do something before call...'
            #{old_name}(*args, &block)
            p '... and something after call.'
          end
        }
      end
    end
  end
end

class UsefulClass
  simple_decorator
  def print_something
    p "I'm a decorated method :)"
  end

  def print_something_else
    p "I'm not decorated :("
  end
end

a = UsefulClass.new
a.print_something
a.print_something_else

simple_decorator выглядит как ключевое слово языка и ведет себя как private; однако, поскольку он удаляет хук method_added, он применяется только к непосредственно следующему определению метода.

...