2014-12-01 6 views
0

Я уверен, что это можно сделать с помощью API отражения.Как обнаружить импорт определенной библиотеки в Scala

Я использую как Casbah, так и spray.json для создания документов JSON в проекте Scala - один для MongoDB, другой - для REST API.

Это может ввести в заблуждение время от времени. Я хотел бы обнаружить и запретить import «неправильной» библиотеки в определенном исходном файле, убедившись, что будущие изменения никогда не будут смешивать оба подхода в одном и том же коде.

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

Приблизительный подход (например, размещение внутри корпуса object, так что он запускается прямо вверх) будет хорошо. То есть как сказать spray.json пространство имен было импортировано в эту область, в Scala?


Предыдущие вопросы: Prevent imports of unauthorized classes in Scala прикасается близко, но больше о Песочница (недоверительной код)

+0

Я не думаю, что отражение - это правильный подход. Должна ли система типоразмеров четко формулировать требования? У вас может быть одна точка доступа для вашего «восстановления», которая принимает «[T: JsonFormat]», и для этого потребуется спрей, а также для вашего материала mongo у вас есть одно «dao», для которого требуется тип Casbah, независимо от того, что импортировано, будут использоваться правильные типы. Если вы действительно настаиваете на этом, я бы рекомендовал использовать что-то вроде Checkstyle как часть вашего процесса сборки; это, вероятно, будет проще и менее запутанным, чем отражение. – lmm

+0

Это отличная идея, @lmm. Позвольте мне перефразировать: вы имеете в виду наложение «этой части использует Casbah», имея ограничение типа/неявное, данное ему через прототипы функций или классов, не требуя импорта вообще. Это сработает. Тем не менее, это все еще не мешает людям случайно попасть в «неправильную сторону», просто набрав «JsString» и давая IDE добавить им импорт для них автоматически. Это часть «проблемы». IDE позволяет легко вводить нежелательные зависимости, и в этом случае они будут обнаружены как странные исключения для сериализации, намного позже. Я бы хотел этого избежать. – akauppi

+0

Я не понимаю, как вы получаете «странные исключения для сериализации». Единственный способ, которым вы можете сериализовать что-то с помощью распылителя - это если у него есть «JsonFormat»; если их нет (как в случае с типами Касбы), вы должны получить ошибку компиляции. Я не знаю Касбаха, но либо он уже работает одинаково, либо вы можете это сделать (имея только одно место, которое сериализуется в Casbah, создавая свой собственный неявный ('CasbahFormat'?) И имея только экземпляры того, что подразумевается для типы Касбы, а не типы распылителей). – lmm

ответ

1

После уточнения ваших комментариев, что я хотел бы сделать это обернуть Casbah сериализации в соответствии с которым типов являются «безопасными». Есть один «шлюз» метод, который делает ваш Casbah сериализации и интерфейс маркера, который говорит, какие типы являются «безопасными», чтобы отправить Крепости

trait CasbahSafe[T] 

object CasbahSafe { 
    implicit val intsAreSafe = new CasbahSafe[Int]{} 
    implicit val stringsAreSafe = new CasbahSafe[String]{} 
    ... 
} 

def saveToMongo[T: CasbahSafe](t: T) = ... 

Тогда saveToMongo можно назвать только с соответствующими типами; если вы попытаетесь вызвать его с помощью JsNumber, вы получите ошибку компиляции. Для составных типов вы можете использовать Shapeless automatic typeclass derivation для получения CasbahSafe для любого класса case, где все поля: CasbahSafe.

Общий эффект очень похож на то, что спрей-json делает с JsonFormat. Уже нельзя было «совершить ту же ошибку в обратном направлении», потому что наличие компилятора принудительно исполняется JsonFormat.

Смежные вопросы