LINUX.ORG.RU

Метаобъектный протокол ли это?

 ,


0

1

Звучит устрашающе-внушительно. Но прочитал вот такое определение,

Метаобъектный протокол — это механизм для определения и использования новых метаклассов.

Метаобъектный протокол определяет множество функций, которые содержат методы для классов. Программирование на уровне метаобъектного протокола — это определение новых классов вместе с методами для этих классов.

перестал боятся и наговнял вот такую реализацию на js



///////////////////////////////////////////////////////////////////////
//prepare:

Object.defineProperty(Object.prototype, "extend", {
 value: function(src){
   for(var i in src){this[i]=src[i]}
 },
 enumerable: false
})


Nigger=function(){} // левый класс
Nigger.prototype.color="black"

/////////////////////////////////////////////////////////////////////////
//implementation:

Class=function(classProperties, opt){
   var f=function(init){
      if(opt) if(opt.object) this.extend(opt.object)
      this.extend(init)
   }
   if(opt) if(opt.parent) {
                             f.prototype=Object.create(opt.parent.prototype)
                             f.prototype.constructor=f
                          }
   f.prototype.extend(classProperties)
   return f
}


//////////////////////////////////////////
//example

Person=new Class({legs: 2, hands: 2, head: 1}, {object: {a: 1}, parent: Nigger})


person1=new Person({name: "Jack"})
person2=new Person({name: "John"})

with(person1){console.log(color, hands, name)}
with(person2){console.log(color, hands, name)}

Person.prototype.footballFan=true // пусть экземпляры нашего класса person будут  футбольными болельщиками
Nigger.prototype.teeth="white" // пусть левый нигер теперь с белыми зубами

with(person1){console.log(color, hands, name, teeth, footballFan)}
with(person2){console.log(color, hands, name, teeth, footballFan)}


//  black 2 Jack
//  black 2 John
//  black 2 Jack white true
//  black 2 John white true

Мы создали конструктор классов, затем определили с помощью него класс. Опционально, в конструкторе можно указать родителя класса — суперкласс (в нашем случае — нигер — совершенно левый класс), а также слоты экземпляров создаваемого класса. Все классы расширяются динамически.

Собственно вопрос: Это он или не он?



Последнее исправление: Pinkbyte (всего исправлений: 4)

Это он или не он

Частично. Метаобъектный протокол позволяет переопределять контроль создания классов, процесс доступа к полям и т. д.

Конструктор классов метаобъектным протоколом не является. Динамическое расширение классов в JS стандартно и неотключаемо.

Пример того, что было бы возможно с метаобъектным протоколом: создать прототип, который можно было бы использовать только в одном объекте; создать прототип, для объектов которого, при записи поля имя поля и значение выводилось бы в console.log; создать прототип, для объектов которого нельзя добавлять поля отсутствующие в прототипе.

monk ★★★★★
()

Не надо говорить слово «класс» применимо к функции. Дождетесь ES6 - будет вам всем синтаксический сахар, тогда и говорите ))

Обсуждаемая тут метаобъектная лабуда кажись даже в пыхе есь под видом трейтов.

deep-purple ★★★★★
()
Ответ на: комментарий от omich

Это вообще-то не с педивикии паста. Но вот с англопедивикии:

A metaobject protocol (MOP) provides the vocabulary to access and manipulate the structure and behavior of objects. Typical functions of a metaobject protocol include:[2]

Creating and deleting new classes Creating new methods and properties Changing the class structure so that classes inherit from different classes Generating or modifying the code that defines the methods for the class

Отсюда, тащемта, еще ясней, что пример соответствует сабжу, в целом.

J-yes-sir
() автор топика
Ответ на: комментарий от monk

Пример того, что было бы возможно с метаобъектным протоколом: создать прототип, который можно было бы использовать только в одном объекте; создать прототип, для объектов которого, при записи поля имя поля и значение выводилось бы в console.log; создать прототип, для объектов которого нельзя добавлять поля отсутствующие в прототипе.

Это все легко можно добавить средствами языка. Например,

Динамическое расширение классов в JS стандартно и неотключаемо.

вполне отключаемо. достаточно запретить писать в прототип, есть свойство объекта writable, а прототип — это всего лишь объект. Все перечисленное решается. Но я бы не стал ничего делать, из этого, так как мы лишаемся простоты и универсальности интерфейса. Но насколько я понял, все ж таки, основная фишка в том, чтобы манипулировать классами так же как объектами, остальное воростепенно.

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

Это все легко можно добавить средствами языка.

Можно пример вот такого: при записи поля имя поля и значение выводилось бы в console.log ?

То есть в коде должно быть что-то вроде

person1=new Person({name: "Jack"})
person1.name = "John" // вывод "name:John"
person1.legs = 1; // вывод "legs:1"

monk ★★★★★
()
Ответ на: комментарий от anonymous

Как профессиональный психиатр, по первому образованию, могу точно сказать, что вы, оба вышеотписавшихся анона, определенно входите в их число. Те факты, что выяснение личности автора поста имеет для вас явно переоцененное значение, до такой степени ценное, что вам не лень вводить каптчу, общаться между собой, флудить на тему, ценность которой для здорового человека равна нулю, говорят о явно выраженных симптомах. Почитай о шизофрении побольше, много интересного узнаешь, и много в себе найдешь, я гарантирую это. Она не обязательно явно проявляется, не у всех шизоидов слюни текут изо рта, не все они под себя ходят и несут ахинею, многие вполне социализированы. Ты, видимо, из их числа. Хотя, конечно, для точного диагноза нужна клиника.

anonymous
()
Ответ на: комментарий от anonymous

общаться между собой, флудить на тему, ценность которой для здорового человека равна нулю,

Ценность бана данного товарища весьма значительна, стоит капчи - он в хорошие теги регулярно срет. Без него реально чище будет.

anonymous
()
Ответ на: комментарий от monk

Person=function(){}
Person.prototype.set=function(name, value){
   this[name]=value; console.log(name+": "+value)
}

person1=new Person

person1.set("name", "John") //  name: John
person1.set("legs", 1) // legs: 1

console.log(person1.name, person1.legs) //  John 1
J-yes-sir
() автор топика
Ответ на: комментарий от anonymous

Ну вот, до кучи еще один симптом: переоценка ценности своего мнения «мое мнение очень важно для всех!!!»(как минимум, мебель непременно прислушается, да!!!). Ты никогда не думал, что твои анонимные высказывания на форумах напрямую влияют на политическую ситуацию в стране и мире?

anonymous
()
Ответ на: комментарий от anonymous

Ценность бана

К тому же, ты и ценность событий воспринимаешь неадекватно, например ценность бана в даном случае, тоже равна нулю, так как товарищ вновь придет под другим ником (если захочет, конечно)

anonymous
()

Это он или не он?

Вместо того чтобы флудить возьми tinyclos и перепиши на js. Это будет точно MOP

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Зачем что-то костылять, если, как выясняется, все возможности MOP нативно есть в объектной системе JS, во всяком случае то что существенно.

J-yes-sir
() автор топика
Ответ на: комментарий от anonymous

давайте не будем играть в демократию. лор не место для обсуждений

stevejobs ★★★★☆
()
Ответ на: комментарий от J-yes-sir

все возможности MOP

напиши ручной диспетчер сообщений. Допустим, чтобы когда в стандартном синтаксисе (через точку) любому объекту посылается сообщение (вызывается функция), чтобы создавалось десять разных классов с рандомной структурой и методом runX (X - номер класса в порядке создания), и этот метод выполняется с единственным аргументом - исходным сообщением.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от J-yes-sir

person1.set(«name», «John»)

Это уже другой синтаксис. Суть метаобъектного протокола именно в том, что можно переопределять стандартные действия: чтение поля, запись поля, наследование, вызов метода.

В случае JS, видимо, синтаксис объектов придётся переопределять в что-то вроде

metaclass = new Metaclass({set : ..., get: ..., send: ..., newClass: ..., newObject: ..})
class = new Class(metaclass, parent, ...);
obj = new Object(class, ...)
obj.set(name, value);
obj.get(name)
obj.send(name, arg1, arg2, ...)

тогда метаобъектным протоколом будут методы metaclass.

monk ★★★★★
()
Ответ на: комментарий от J-yes-sir

Синтаксис другой, а суть та же.

Тогда метаобъектный протокол существует в любом языке. Аналог https://developer.gnome.org/gobject/stable/chapter-gobject.html#gobject-insta... я могу написать на чём угодно от ассемблера до хаскеля.

monk ★★★★★
()
Ответ на: комментарий от J-yes-sir

все возможности MOP нативно есть в объектной системе JS

Нет нету. Другое дело, что можно прикрутить эти возможности опираясь на базовые, как это делает тот же tinyclos, но это уже другой разговор. Так-то и в крестах можно замутить MOP и динамические классы, да даже запилить свой мини-лисп... Где-то я это уже слышал.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

проблема в том, что не везде, мягко говоря, нативно поддерживается прототипное ООП, и выглядеть это будет не как органичная часть языка, а как прибитый гвоздями костыль.

J-yes-sir
() автор топика
Ответ на: комментарий от monk

до хаскеля.

В смысле? На хаскеле интерпретатор JS ты можешь написать, но интегрировать эту среду в хаскель не сможешь. В хаскеле нет динамики.

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

не везде, мягко говоря, нативно поддерживается прототипное ООП

А при чём тут оно? Мы ведь про метаобъектный протокол. Если твоё ООП позволяет переопределить действия при

obj.prototype = ...
obj.field = ...
obj.not-defined-method(...)
f(obj.field)

Пример того, где он полезен: можно написать obj = get_db_obj(id); console.log(obj.f1.f2.f3), где get_obj_id возвращает ссылку на строку таблицы в базе данных, а obj.f1.f2.f3 возвращает результат от «select t3.f3 from t1 join t2 on t1.f1 = t2.id join t3 on t2.f2 = t3.key where t1.id=id».

monk ★★★★★
()
Ответ на: комментарий от monk

А при том, что в моем, например, стартовом примере, класс Nigger определен не с помощью волшебной функции, а в рамках стандартного ООП, что не мешает ему интегрироваться в метаклассовую систему, и для этого ничего не надо. Все консистентно, все классы «разговаривают на одном и том же языке»

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

класс Nigger определен не с помощью волшебной функции, а в рамках стандартного ООП, что не мешает ему интегрироваться в метаклассовую систему, и для этого ничего не надо

Он не интегрирован в метаклассовую систему. В примере ты используешь только возможности прототипного ООП. А для метаклассовой системы ты сам предлагаешь использовать синтаксис obj.set(), obj.get() вместо стандартного

monk ★★★★★
()
Ответ на: комментарий от monk

Я считаю, что питон говно. Мало того, что сам язык слабый, со скопированным с жабы ООП, так еще и сами питонисты со своим быдлоподходом городят костыли на каждый шаг. Как достать все дивы из HTML-документа? /<div.*?/\div>/g? не, не питоник, надо подключить MONSTRofPARSINGsuperHTMLandNOTxhtmlLIB.py, а так некомильфо. И все у них, блять, через такую жопу.

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

Регекспы в питоне тоже встроены. Никто с паяльником над тобой не стоит и MONSTRofPARSINGsuperHTMLandNOTxhtmlLIB использовать не заставляет.

P.S. В JS тоже есть парсеры HTML

monk ★★★★★
()
Ответ на: комментарий от J-yes-sir

Этот синтаксис не выходит за рамки стандартного, это всего лишь методы.

Ну так и в GObject весь синтаксис — обычные структуры и функции.

#define MAMAN_TYPE_BAR                  (maman_bar_get_type ())
#define MAMAN_BAR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
#define MAMAN_IS_BAR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
#define MAMAN_BAR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
#define MAMAN_IS_BAR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
#define MAMAN_BAR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))

struct _MamanBar
{
  GObject parent_instance;

  /* instance members */
};

struct _MamanBarClass
{
  GObjectClass parent_class;

  /* class members */
};

G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);

static GObject *
maman_bar_constructor (GType                  gtype,
                       guint                  n_properties,
                       GObjectConstructParam *properties)
{
  GObject *obj;

  {
    /* Always chain up to the parent constructor */
    obj = G_OBJECT_CLASS (maman_bar_parent_class)->constructor (gtype, n_properties, properties);
  }
  
  /* update the object state depending on constructor properties */

  return obj;
}

static void
maman_bar_class_init (MamanBarClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->constructor = maman_bar_constructor;
}

static void
maman_bar_init (MamanBar *self)
{
  /* initialize the object */
}

MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);

_MamanBarClass — вполне нормальный метакласс. А если чего не хватает, так можно докрутить как в твоих set(), get().

monk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.