LINUX.ORG.RU

Для smalltalk или ruby — ни в чём.

Там, где методы не совсем сообщения (Java, C++) обработать получение произвольного сообщения.

Бывают также системы, где методы совсем не сообщения (CLOS). Там нельзя указать, кто является получателем сообщения, так как обработка зависит от нескольких аргументов, а не одного.

monk ★★★★★ ()

Разница в том, что в объекте может не быть метода, но сообщение он всё равно обработает. Так-то, вышеотписавшиеся!

yoghurt ★★★★★ ()

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

NeXTSTEP ★★ ()

Вот, ты можешь получить сообщение, подумать «ну и фигню же мне тут прислали» и забить на него. А объект в С++ так не может.

ugoday ★★★★★ ()

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

waker ★★★★★ ()

Сообщения обрабатываются пользовательским кодом, а методы — рантаймом языка. Как-то так.

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

ну когда закончишь тот семестр — расскажешь, как вызвать произвольный метод зная только сигнатуру по указателю void *.

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

inb4 кукареку:

Этот код семантически соответствует следующему коду на Эрланге:

someThread ! {t, someMethodOfT}.

с той разницей, что в эрланге можно дропать все негодные сообщения, а в крестах — нельзя.

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

Разница в том, что в объекте может не быть метода, но сообщение он всё равно обработает.

В python есть __getattr__ и можно обрабатывать вызов несуществующего метода:

from functools import partial


class MyCls(object):
    def exists(self):
        print('exists method')
        
    def _handle_not_exists_method(self, name, *args, **kwargs):
        print('call not exists method: {}, {}, {}'.format(name, args, kwargs))
        
    def __getattr__(self, name):
        return partial(self._handle_not_exists_method, name)
        

inst = MyCls()

In [15]: inst.exists()
exists method

In [16]: inst.whtf_i_call()
call not exists method: whtf_i_call, (), {}

In [17]: inst.whtf_i_call(1, 2, x=3)
call not exists method: whtf_i_call, (1, 2), {'x': 3}

И в python «вызов метода», а не «отправка сообщения».

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

Ещё раз: представь, что в эрланге можно посылать не любые сообщения, а только вида

{#atom(), #atom(), #any()}.

Тогда получается соответствие:

reinterpret_cast<t*> a -> b(d);
 
   Λ
   |
   V

a ! {t, b, d}.

Необходимость в данном случае кастовать в t* (и, соотв., посылать атом t в каждом сообщении) определяется только особенностью типизации и рантайма крестов. В каком-нибудь пайтоне этого можно было не делать. А если бы там можно было перегрузить точку для любого терма, ограничений на сообщения не было бы вообще и внешнее сходство было бы полным.

Ну и да, тупишь здесь только ты.

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

полный бред.

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

ты сначала определись — таки эрланг, или C++. когда покажешь, как дернуть по указателю void * метод с известной сигнатурой, но неизвестным классом — возвращайся. можешь после окончания 2го семестра, когда виртуальные методы освоишь.

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

ты не поверишь, но она как раз и содержит указатели, которые резолвятся во время компиляции. (во всяком случае, в C++ — я не знаю как это в других подобных языках реализовано на низком уровне)

waker ★★★★★ ()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от fmdw

вот это, кстати

вызов метода резолвится на этапе компиляции

я не писал.

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

Ты крайне неловко пытаешься вылезти из лужи, в которую плюхнулся.

Если все указатели «резолвятся на этапе компиляции», зачем vmt тащится в рантайм?

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

Ты крайне неловко пытаешься вылезти из лужи, в которую плюхнулся.

ага, это особенно заметно по тому, как ты цитируешь своего вымышленного друга, выдавая цитаты за мои.

Если все указатели «резолвятся на этапе компиляции»

ну чего прямо сразу все? где я такое писал? указатели на методы - да. есть что возразить?

зачем vmt тащится в рантайм?

ты еще спроси зачем скомпилированный код тащить в рантайм.

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

Судя по тому, что ты просишь вызвать метод у void*, a не какого-то базового интерфейса, про ООП в крестах ты не знаешь ничего. Продолжая аналогию с эрлангом, ты бы ещё попросил в нём послать сообщение функции или списку.

Судя по игнорированию замечания про питон — ООП в динамических языках нам тоже неведом.

ты еще спроси зачем скомпилированный код тащить в рантайм.

Не знаешь что ответить — переходи к петросянству. Срач начинает быть очень скучным.

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

Хватит спорить попусту. Речь была про то, что vmt заполняется «статически». Вызов происходит динамически(но, кстати, по статическому смещению в vmt). Вы оба не слишком корректно выразились.

anonymous ()

Сообщение - это то, что мы отправляемых, метод - это то, как на сообщение будут реагировать. Все вроде просто.

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

Судя по тому, что ты просишь вызвать метод у void*, a не какого-то базового интерфейса, про ООП в крестах ты не знаешь ничего.

это непринципиально. пусть вместо void * будет базовый класс, вот такой

class BaseClass {
};

есть указатель BaseClass *ourObject;

нужно вызвать у него любой метод, например «void foo()».

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

Судя по игнорированию замечания про питон — ООП в динамических языках нам тоже неведом.

ведом. и даже про __getattr__, внезапно, в курсе :) но как оно там внутри работает — не знаю, и не интересно.

Не знаешь что ответить — переходи к петросянству. Срач начинает быть очень скучным.

ты давай, переходи к делу — жги про виртуальные методы, базовые интерфейсы, и т.п., а то я все никак ответа на свой вопрос не дождусь.

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

С тем же успехом я могу сказать, что паттерн-матчинг (или чем ещё можно обрабатывать сообщения) «статически» превращается в jmp по статическим указателям. Смысла будет столько же, а именно — близко к нулю.

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

и даже про __getattr__, внезапно, в курсе :) но как оно там внутри работает — не знаю, и не интересно.

Раньше(года 2-3 назад) в дефолтной реализации просто был словарь. Думаю, что так и осталось.

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

Смысл тут будет в том, что сама статическая структура vmt будет создана под «сообщения», а заполнятся будет уже «методами». Ну это если вдруг вводить термин сообщение в язык, которому это чуждо. В objective-c разница более ощутима. Посылаем сообщение, а рантайм ищет нужный метод у объекта. Сообщение там ещё называется селектором метода иногда.

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

придирки к словам — первый признак шланга.

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

не, селектор — это тип сообщения, например @selector(myMethod::). само сообщение — это пакет, содержащий селектор+параметры (определяется реализацией конкретного языка/рантайма)

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

Раньше(года 2-3 назад) в дефолтной реализации просто был словарь. Думаю, что так и осталось.

с виду — просто функция, которая дергается при вызове любого метода.

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

В руби отправка сообщений как в смолтоке, а в смолтоке она Ъ. А ты просто не в ту сторону прочитал

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

Смысл тут будет в том, что сама статическая структура vmt будет создана под «сообщения», а заполнятся будет уже «методами».

Не распарсил. Мой поинт:

VMT составляется статически <-> receive компилируется статически

смещение берётся из VMT динамически <-> сообщение матчится динамически

VMT составляется компилятором <-> recieve пишется ручками

Разница только в последнем пункте. Может ты мне объяснишь, что waker плёл про динамическую диспетчеризацию vs статические указатели?

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

объяснишь, что waker плёл про динамическую диспетчеризацию vs статические указатели?

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

waker ★★★★★ ()

Грубо говоря, при передаче сообщения решение об ответе _всегда_ принимает объект, а при вызове метода решение принимает рантайм.

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

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

динамическая типизация: obj.meth()

статическая типизация: выяснить название соотв. интерфейса, кастануть и вызвать. если такового нет и нет возможности выпороть автора кода — «увольняться с этой долбаной, долбаной...».

целый тред увиливал, а теперь объясни: чем тебе подсмотр указателя метода в таблице не обработка сообщения? только без сливов про «вызов метода — это конкретный указатель на код», а то реально тянет послать учиться.

t184256 ★★★★★ ()

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

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

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

Строго говоря, там никакой диспетчеризации нет - мы просто вызываем метод по указателю. В этом и было одно из преимуществ крестовой модели - дешевый вызов виртуальных методов.

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

Обсуждают сообщение, методы и диспетчеризацию. C++, Objective-C, Python, Ruby, Smalltalk и пр. тут как примеры.

forCe ()

вызов метода выполняется в контексте вызывающего объекта, а сообщение обрабатывается методом в контексте вызываемого объекта. Особо разница будет ощутима на потоках

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

чем тебе подсмотр указателя метода в таблице не обработка сообщения?

тем, что метод привязан к типу объекта (классу), а сообщение - нет.

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