На рубине, почему включение является частным, и расширение является общедоступным?

В рубине, в чем причина include является частной, а Object#extend является общедоступной?

Ответ 1

Object#extend должен быть общедоступным, иначе вы не сможете его использовать. В конце концов, его цель состоит в том, чтобы смешивать модуль в объект, поэтому вы обычно называете его как obj.extend(Foo), что невозможно при использовании частных методов.

Module#include обычно используется только внутри тела модуля так:

class Bar
  include Foo
end

т.е. его обычно называют без получателя, поэтому он не должен быть общедоступным. Конечно, это тоже не должно быть частным.

Моя догадка - причина, почему она является частной, заключается в том, что она более инвазивная, потому что она изменяет поведение каждого экземпляра Bar, тогда как Object#extend изменяет только один объект. Следовательно, Module#include в некотором смысле "более опасен" и, таким образом, становится частным.

Я не знаю, является ли это фактической причиной, но она согласуется с другими аналогичными методами, такими как Module#define_method.

Ответ 2

Чтобы иметь возможность запускать Foo.include(Bar) в любой момент, скорее всего, станет источником очень неприятных ошибок.

Ответ 3

Чтобы дополнить ответ Jörg W Mittag, Object # extend также можно использовать для включения методов экземпляра модуля, которые будут использоваться на уровне класса (который также будет доступен для всех экземпляров этого класса):

module Foo
  def bar (baz)
  end
end

class Qux
  extend Foo

  bar 'asdf'
end