Delphi RTL включает очень мощный механизм выражений, который является одной из основ архитектуры Live Bindings, но может использоваться как отдельный механизм для обработки выражений. Это сообщение в блоге предлагает краткое введение в тему.
В Delphi RTL есть много скрытых жемчужин. Один из них — машина выражения. Недавно у меня было несколько разговоров с давним разработчиком Delphi, который искал похожую функцию, не понимая, что она присутствует в продукте много лет. Я знал, что написал несколько демонстраций и документации, поэтому потратил немного времени на их поиск и нашел несколько. Эта тема очень сложна, и я не смогу охватить ее полностью, но для простых сценариев вам действительно понадобится очень мало кода для синтаксического анализа и обработки выражения.
Прежде чем я начну с реальной темы, я также хотел бы упомянуть, что мы недавно обнаружили эту функцию в новом компоненте VCL NumberBox (добавленном в Delphi 10.4.2, см., Например, https://blog.marcocantu.com/blog/2021-february—new-vcl-controls-1042.html ). Этот компонент позволяет конечным пользователям вводить выражение и заменять его полученным значением. Неудивительно, что он использовал существующий механизм выражений и делает это, вызывая упрощенный метод класса
В этом фрагменте кода LText — это строка с выражением, а Value — результат с плавающей запятой. Метод класса TBindings.CreateExpression — это ярлык, который может упростить код, но я бы предпочел познакомить вас с некоторыми подробностями.
Table of Contents
Ключевые концепции связывающих выражений
Приведенный выше код создает объект TBindingExpression, основной класс этого движка. Как следует из названия, он выходит за рамки простого оценщика выражений, но может «связывать» или связывать выражение с внешними объектами, используя RTTI для интеграции.
Еще одна ключевая концепция выражений привязки заключается в том, что они не оценивают ввод полностью динамическим образом, а скорее требуют операции синтаксического анализа (называемой компиляцией), обрабатывающей текст, и операции оценки, выполняющей окончательную обработку. Конечно, если вы не меняете текст выражения, вы можете один раз скомпилировать и многократно оценить выражение с разными значениями для связанных объектов.
Давайте перейдем к демонстрации
Для моей первой демонстрации я создал форму с двумя элементами управления Memo, один для ввода выражения, а второй для отображения вывода. Цель здесь — обрабатывать строки, а не числовые значения. Код для единственной кнопки напрямую использует объекты выражения привязки, как показано ниже:
[crayon-676860484516d498363886/]
Не то чтобы это было очень полезно, поскольку единственные предопределенные операции для строк — это конкатенация, поэтому вы можете ввести ввод:
[crayon-676860484516f438389705/]
и в результате получите Hello world . Обратите внимание на двойные кавычки во вводе!
Связывание объекта
Все становится интересно, если вы привязываете выражение к объекту. Для этого я создал простой класс, подобный следующему (здесь я пропустил частные поля и методы):
[crayon-6768604845170826057396/]
Теперь я могу изменить код, чтобы добавить привязку к выражению, добавив к методу Compile ассоциацию объекта с символическим именем (вы можете рассматривать его как имя объекта для механизма выражения):
[crayon-6768604845171436103258/]
С этим расширением я теперь могу использовать этот объект в выражении вроде. Например, после присвоения «John» имени объекта pers в коде выражение:
[crayon-6768604845172456273362/]
приведет к тому, что Джон счастлив . Но я также могу использовать выражение:
[crayon-6768604845173937868824/]
который будет выполнять преобразование типа из Integer в строку.
Функции привязки
Выражения привязки ограничены объектами, но помимо доступа к свойствам они также могут выполнять методы. Поэтому вы можете создать класс с несколькими методами, которые будут использоваться в выражении:
[crayon-6768604845174236125485/]
Чтобы вызвать эти методы, вам нужно привязать объект этого типа:
[crayon-6768604845175031964867/]
Теперь вы можете писать такие выражения, как:
[crayon-6768604845176644298645/]
Результат: В двойном возрасте Джону будет 66 лет.
Демо-интерфейс
Не то чтобы фантастика, но это демонстрация в действии:
Только касание поверхности
Это введение касается только поверхности, поскольку выражение привязки позволяет связывать элементы управления, а также позволяет регистрироваться для уведомлений (своего рода механизм обратного вызова). Я нашел еще несколько демонстраций, и скоро постараюсь опубликовать о них в блоге.