Динамический вызов функции в классе Racket в сочетании с apply - PullRequest
2 голосов
/ 10 марта 2019

TL; DR

Мне нужна комбинация функций send/apply и dynamic-send. Чтобы он нашел метод объекта, основанный на символе , а распаковывает список аргументов.

Фон и дополнительная информация

Для школьного проекта я посылаю несколько «команд» по сети с помощью tcp-connect Ракета. В конце получателей эта команда должна выполнить метод из класса и передать его параметры.

Рассмотрим следующее полученное «сообщение»:

(define message (list 'set-switch! '3 'on))
(define method-name (car msg))  ;'set-switch!
(define parameters (cdr msg))   ;(list '3 'on)

и следующий класс:

(define light%
  (class object%
    (super-new)

    ...

    (define/public (set-switch! id mode)
      (vector-set! switches id mode))))

Проблема в том, что при выполнении этого оператора

(dynamic-send light-class method-name parameters)

он отлично находит метод set-switch!, но вызывает его только с одним параметром (list '3 'on).

The Racket документы упоминают эти три функции для классов:

  • (send obj-expr method-id arg), который просто выполняет метод объекта
  • (send/apply obj-expr method-id arg-list-expr), который выполняет метод И распаковывает список аргументов
  • (dynamic-send obj method-name v), который находит имя метода на основе символа

Мне кажется, что мне нужно что-то вроде (dynamic-send/apply obj method-name arg-list-expr), объединяющее два последних упомянутых.

Примечание: я знаю, что могу просто принять списки в качестве параметров и использовать car и cdr в самих функциях, чтобы получить правильные значения. Но это не то, что я хочу.

1 Ответ

2 голосов
/ 10 марта 2019

dynamic-send - это функция (также известная как процедура; например, car, vector-set!, +), поэтому вы можете использовать apply:

(apply dynamic-send light-class method-name parameters)

Или даже просто:

(apply dynamic-send light-class message)

Причина, по которой send имеет вариант send/apply, заключается в том, что send является формой (также известной как синтаксис; например, let, define, if), поэтому apply не имеет t работает и, следовательно, send/apply предоставляется отдельно.

...