В рубине, в чем причина 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