Comments 16
Я раньше пытался понять концепцию метаклассов, сравнивая их с фабриками классов.
Но это объяснение понятнее, спасибо!
Но это объяснение понятнее, спасибо!
Система метаклассов Python напоминает таковую у Smalltalk. Только в Python нет ProtoObject.
Подскажите, есть какая-нибудь известная компания, которая использует Smalltalk на production-е? У Pharo есть такой список, но узнаваемых имён там нет.
Подскажите, есть какая-нибудь известная компания, которая использует Smalltalk на production-е? У Pharo есть такой список, но узнаваемых имён там нет.
Насколько я знаю, в Python-е как раз вариант с одним метаклассом на всех, разве нет?
Насчет известных компаний — мне не очень хочется тратить время на этот вопрос. Скорее всего, их мало или совсем нет. У Cincom-а еще недавно упоминались Texas Instruments и JPMorgan — не знаю, можно ли отнести их к «известным». Когда-то AMD относили к пользователям Smalltalk-а, но не знаю, как сейчас. Больше и вспомнить ничего не удается.
Насчет известных компаний — мне не очень хочется тратить время на этот вопрос. Скорее всего, их мало или совсем нет. У Cincom-а еще недавно упоминались Texas Instruments и JPMorgan — не знаю, можно ли отнести их к «известным». Когда-то AMD относили к пользователям Smalltalk-а, но не знаю, как сейчас. Больше и вспомнить ничего не удается.
Насколько я знаю, в Python-е как раз вариант с одним метаклассом на всех, разве нет?
Метакласс в Python'e указывается явно:
class Foo(object):
__metaclass__ = MyMetaClass
или в python 3
class Foo(object, metaclass=MyMetaClass):
...
class FooMeta(type):
pass
class Foo(object, metaclass=FooMeta):
pass
class Bar(object):
pass
type(Bar) == <class 'type'>
Bar.__mro__ == (<class '__main__.Bar'>, <class 'object'>)
type(Foo) == <class 'FooMeta'>
Foo.__mro__ == (<class '__main__.Foo'>, <class 'object'>)
type(FooMeta) == <class 'type'>
FooMeta.__mro__ == (<class '__main__.FooMeta'>, <class 'type'>, <class 'object'>)
type(type) == <class 'type'>
type.__mro__ == (<class 'type'>, <class 'object'>)
type(object) == <class 'type'>
object.__mro__ = (<class 'object'>,)
Еще бы не помешала статья «Зачем учить Smalltalk?»
Спасибо за статью. Кстати, вы не знаете, чем было вызвано нежелание вводить метаклассы явно?
В Little Smalltalk они есть и вполне материальны:
Ну, разве что, они не хранятся в глобальном словаре имен, но в то же время, это полноценный объект со своим именем, полями, размером и т.д.
В Little Smalltalk они есть и вполне материальны:
->Object class
MetaObject
->Object class class
Class
->Object class class class
MetaClass
->Object class class class class
Class "дальше зацикливается"
Ну, разве что, они не хранятся в глобальном словаре имен, но в то же время, это полноценный объект со своим именем, полями, размером и т.д.
Знать — не знаю. Но могу предположить: люди с метаклассами работать не должны, имена им присваивать нет смысла. На материальность отсутствие имен не влияет.
Я думаю, именно из-за зацикленности цепочки метаклассов. Нет смысла давать имя сущности, которая является не полноценной экстраполяцией отношения class-of, а всего лишь затычкой для оправдания аксиомы «у каждого объекта должен быть класс». Пусть даже этой экстраполяции нельзя придать разумный смысл.
Ну, как же — «затычкой»?! Об этом же статья: метаклассы определяют поведение классов, давая возможность задать произвольный «конструктор» или любое удобное поведения с нормальным полиморфизмом. Видимо, не удалось донести основную мысль. :)
…А вообще, в очередной раз я не понимаю чего-то умного. Какие-то экстраполяции каких-то отношений, какие-то аксиомы… Есть необходимость где-то хранить поведение. Решили однажды хранить в классах (со всеми хорошими и нехорошими последствиями — ну, не придумали тогда еще клонирования, что поделаешь :) — придерживаемся этого решения, тем более что оно неплохо подходит и для решения данной проблемы. Есть необходимость — нашли наиболее простое решение (уже реализованное) — потом придумали термин. Никаких размышлений о «разумных смыслах», следовании придуманным аксиомам, высосанным из пальца паттернам и прочей наукообразности, придающей глубину и значительность «принципам объектного программирования» …и убивающим саму идею.
…А вообще, в очередной раз я не понимаю чего-то умного. Какие-то экстраполяции каких-то отношений, какие-то аксиомы… Есть необходимость где-то хранить поведение. Решили однажды хранить в классах (со всеми хорошими и нехорошими последствиями — ну, не придумали тогда еще клонирования, что поделаешь :) — придерживаемся этого решения, тем более что оно неплохо подходит и для решения данной проблемы. Есть необходимость — нашли наиболее простое решение (уже реализованное) — потом придумали термин. Никаких размышлений о «разумных смыслах», следовании придуманным аксиомам, высосанным из пальца паттернам и прочей наукообразности, придающей глубину и значительность «принципам объектного программирования» …и убивающим саму идею.
Затычка — это вон тот самый «Metaclass class». Почему для классов классов надо вводить свои собственные метаклассы, а сами метаклассы обходятся общим на всех Metaclass? Непоследовательно и выглядит как логический костыль.
А похоже дело в том, что для класса Metaclass нельзя придумать нормальных методов. Если класс хранит методы объектов, метакласс хранит методы класса, а Metaclass хранит методы всей объектной системы в целом, то какие методы должен хранить Metaclass class? Позволяющие создавать произвольные объектные системы?
Вот тут мозги философов от объектного программирования поплавились. Поэтому от греха подальше цепочку замкнули саму на себя. А вот в Ruby, насколько мне известно, мозги решили не щадить.
А похоже дело в том, что для класса Metaclass нельзя придумать нормальных методов. Если класс хранит методы объектов, метакласс хранит методы класса, а Metaclass хранит методы всей объектной системы в целом, то какие методы должен хранить Metaclass class? Позволяющие создавать произвольные объектные системы?
Вот тут мозги философов от объектного программирования поплавились. Поэтому от греха подальше цепочку замкнули саму на себя. А вот в Ruby, насколько мне известно, мозги решили не щадить.
На случай, если вы не толсто троллите, а тонко не понимаете, поясню еще раз.
Классы обладают различным поведением, поэтому нужны метаклассы, экземплярами которых в отношении 1:1 являются эти классы.
Метаклассы обладают одинаковым поведением поэтому нужен всего один Metaclass, экземплярами которого являются все метаклассы.
Metaclass обладает особым поведением, поэтому ему нужен свой метакласс, экземпляром которого он будет.
Metaclass class обладает таким же поведением, как и все метаклассы, поэтому является экземпляром Metaclass.
Вот иллюстрация:
Классы обладают различным поведением, поэтому нужны метаклассы, экземплярами которых в отношении 1:1 являются эти классы.
Метаклассы обладают одинаковым поведением поэтому нужен всего один Metaclass, экземплярами которого являются все метаклассы.
Metaclass обладает особым поведением, поэтому ему нужен свой метакласс, экземпляром которого он будет.
Metaclass class обладает таким же поведением, как и все метаклассы, поэтому является экземпляром Metaclass.
Вот иллюстрация:
Point allMethods size." 440 <- Methods count in Point instances"
Point class allMethods size." 815 <- Methods count in Point class"
Point class class "This is Metaclass"
allMethods size." 738 <- Methods count in all metaclasses"
Point class class class "This is Metaclass class"
allMethods size." 814 <- Methods count in Metaclass "
Point class class class class "This is Metaclass again"
allMethods size." 738 <- Methods count in all metaclasses"
Окей, я понял. Метаклассы — это место, которое пришлось выдумать, чтобы куда-то пристроить методы объектов. И потом ещё понадобился Metaclass, чтобы куда-то пристроить методы метаклассов. И ещё Metaclass class, чтобы пристроить методы самого Metaclass. Для Metaclass class каких-то характерных лично для него методов уже не выдумали, поэтому он просто сделан экземпляром Metaclass.
Sign up to leave a comment.
Метаклассы в Smalltalk