Как объявить анонимный миксин, используя параметр типа в Scala - PullRequest
3 голосов
/ 31 мая 2011

Были заданы некоторые вопросы, которые в некоторой степени связаны с этой проблемой, но, похоже, они не совсем подходят.

Я использую шаблон Cake для установки системы «Storage» на месте в рабочем коде и системы-заглушки для тестирования. Это все замечательно, но есть класс, который создается в исходном классе, которому также нужно смешать эту систему хранения заглушек. Так как она скрыта внутри реализации, у меня нет к ней доступа.

Вещи выглядят так:

class Main { this: Storage =>
  ...
  val used = Used(...)
  ...
}

class Used { this: Storage =>
  ...
}

При тестировании "Б" я просто new Used with StubStorage и выхожу. Я делал то же самое с Main, но это было до того, как он использовал Used. Теперь, когда Main делает наивное создание Used У меня есть эта проблема.

Я хотел попробовать это так:

class Main[T <: Storage] { this: T =>
  ...
  val used = Used[T](...)
  ...
}

class Used[T <: Storage] { this: T =>
  ...
}
object Used {
  def apply[T <: Storage](...) = new Used(...) with T
}

Но, конечно, это не работает, потому что у компилятора недостаточно информации для обнаружения T. Есть ли волшебный рецепт для этого? Я немного поигрался с этим, и он кажется достаточно громоздким, так что стандартный метод инъекции ОО на самом деле меньше проблем, но я мог что-то упустить.

Я посмотрел на неявную концепцию Factory, но не могу придать ей форму, чтобы она работала на миксинах.

РЕДАКТИРОВАТЬ : Удивительно, насколько ясно дает написание вопроса. :) Я не решил проблему так, как планировал, но есть реальное решение проблемы:

trait UsedProvider {
  def createUsed = Used.apply _
}

class Main { this: Storage with UsedProvider =>
  val used = createUsed(...)
}

Тогда я бы просто сделал следующее в тесте: new Main with StubStorage with StubUsedProvider.

1 Ответ

0 голосов
/ 01 июня 2011

Я также не решил вашу первоначальную проблему, но вы рассматривали возможность использования абстрактного класса для Main и укажите значение для used там, где оно вам нужно?

abstract class Main { this: Storage =>
  val s = "s"
  val used: Used
}

Затем создайте экземпляр, как этот:

val main = new Main with StubStorage { val used = new Used(s) with StubStorage }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...