LINUX.ORG.RU

Мультиметод.

 


0

3

Пишу метод. Есть метод А, который менее специфичен по первому аргументу, есть метод Б, менее специфиченый по второму аргументу. По остальным аргументам специфичность одинакова. Как настроить комбинатор так, чтобы при вызове метода выполнялся сначала метод Б и только потом А?

(defclass A ())

(defclass A1 (A))

(defclass B ())

(defclass B1 (B))

(defgeneric method (A-arg B-arg))

(defmethod method ((A-arg A) (B-arg B1))
  "Метод A"
  t)

(defmethod method ((A-arg A1) (B-arg B))
  "Метод Б"
  t)
★★★★★

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

У вас будет выполняться только один метод. Т.е., не будет «сначала метод Б и только потом А», а будет либо А, либо Б.

Это все происходит, потому что дефолтный комбинатор методов выполняет один (и только один) primary-метод и, в дополнение к нему, :before, :after и :around-методы.

Чтобы поменять «важность» аргументов при определении спефицичности методов, надо использовать опцию :argument-precedence-order в defgeneric.

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

А как вы собираетесь эти методы линейно упорядочивать?

В соответствии с правилами языка, конечно же. А вы как думали?

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

У вас будет выполняться только один метод. Т.е., не будет «сначала метод Б и только потом А», а будет либо А, либо Б.

Ладно, перестаю мудрить, обхожу задачу. Создам обыкновенную функцию. Ато крыша уже поехала от этого CLOS.

Спасибо.

ados ★★★★★
() автор топика

Чтобы вызывались именно оба метода, и в указанном порядке - надо указать порядок проверки аргументов в defgeneric, и там же - комбинатор методов progn с опцией :order в :most-specific-first

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

Я правильно понял?

(defclass A ())

(defclass A1 (A))

(defclass B ())

(defclass B1 (B))

(defgeneric method (A-arg B-arg)
  (:method-combination progn 
		       :argument-precedence-order (B-arg A-arg)
		       :order :most-specific-first)

(defmethod method ((A-arg A) (B-arg B1))
  "Метод A"
  t)

(defmethod method ((A-arg A1) (B-arg B))
  "Метод Б"
  t)

;;; Вызов того, что мне надо
(method progn 
	A  ; класса A1 которое
	B) ; класса B1 которое
ados ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Очень хочется, чтобы методы А или Б (а желательно оба) могли комбинироваться также и стандартным комбинатором в других методах. Оба являются по любому крайними в комбинациях.

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

Т.е.

(defmethod method progn ((A-arg A) (B-arg B1))
  (print "Метод A"))

(defmethod method progn ((A-arg A1) (B-arg B))
  (print "Метод Б"))

;;; Вызов того, что надо
(method a b) 
korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Дело в том, что есть ещё методы, которые комбинируются с А или Б стандартным комбинатором. Я так понял теперь надо создавать новый метод и в них дублировать код метода А или Б.

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

Способ комбинации определяется в дженерике, в методах переопределить способ комбинации, насколько я знаю, нельзя.

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

Одна обобщенная функция - один комбинатор, понятно.

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