TBEL 언어 가이드
이 가이드는 TBEL 문법, 데이터 유형, 컬렉션, 흐름 제어 구문을 다룹니다. 내장 유틸리티 함수 전체 목록은 헬퍼 함수 레퍼런스를 참고하세요.
문법 제약
섹션 제목: “문법 제약”TBEL은 MVEL을 바탕으로 합니다. 몇 가지 문법 규칙이 JavaScript와 다릅니다.
foreach를 씁니다(for...of/for...in대신). 전통적인for반복문도 지원합니다.- 명시적인
if문 밖에서 삼항 식을 쓸 때는 괄호로 감싸야 합니다. - 여러 문장은 세미콜론으로 구분합니다. 마지막 문장 뒤의 세미콜론은 생략할 수 있습니다.
단순 속성 식
섹션 제목: “단순 속성 식”컨텍스트 객체의 속성에 바로 접근합니다.
msg.temperature불리언 식
섹션 제목: “불리언 식”return (msg.temperature > 10 && msg.temperature < 20) || (msg.humidity > 10 && msg.humidity < 60);표준 연산자 우선순위가 적용됩니다. 실행 순서는 괄호로 정합니다.
여러 문장
섹션 제목: “여러 문장”문장은 세미콜론으로 구분합니다. 마지막 문장의 값이 스크립트의 반환 값입니다.
var a = 2;var b = 3;a + b; // returns 5유형 변환
섹션 제목: “유형 변환”TBEL은 호환되는 유형을 자동으로 변환합니다.
"123" == 123; // true맵은 인라인으로 만들며, 메모리 추적 기능이 내장된 자체 구현을 씁니다.
var map = {"temperature": 42, "nested": "508"};값 접근
섹션 제목: “값 접근”map.temperature // dot notationmap.get("temperature") // method callmap["temperature"] // bracket notation안전 탐색 연산자를 쓰면 없는 키에서 NullPointerException이 나지 않습니다.
if (map.?nonExistingKey.smth > 10) { }명시적인 entrySet():
foreach (element : map.entrySet()) { element.getKey(); // or element.key element.getValue(); // or element.value}암묵적(값을 반복):
foreach (value : map) { // process each value}map.temperature = 0; // set valuemap.put("humidity", 73); // add entrymap.putIfAbsent("temperature1", 73); // add if missingmap.replace("temperature", 56); // replace valuemap.replace("temperature", 56, 42); // conditional replacemap.remove("temperature"); // remove entryvar keys = map.keys(); // get all keysvar values = map.values(); // get all valuesvar size = map.size(); // entry countvar memorySize = map.memorySize(); // memory in bytesmap.sortByKey(); // sort by key in-placevar sorted = map.sortByValue(); // sort by value in-placemap.putAll({"test": 12, "input": {"http": 130}}); // merge another mapisMap(map); // type check → true수정할 수 없는 맵
섹션 제목: “수정할 수 없는 맵”var original = {};original.humidity = 73;var unmodifiable = original.toUnmodifiable();unmodifiable.put("temperature1", 96); // throws error: Map is unmodifiable리스트
섹션 제목: “리스트”리스트는 메모리 추적 기능이 있는 자체 구현을 씁니다. 인라인 생성만 허용합니다.
생성과 접근
섹션 제목: “생성과 접근”var list = ["A", "B", "C"];list[0]; // "A"list.size(); // 3foreach (item : list) { var smth = item;}
for (var i = 0; i < list.size; i++) { var smth = list[i];}추가 연산
섹션 제목: “추가 연산”list.add(3, "sensor"); // insert at indexlist.push("sensor"); // append to endlist.unshift("r"); // prepend to startlist.addAll(["sensor", 4, 67]); // append all elementslist.addAll(2, ["x", "y"]); // insert all at index삭제 연산
섹션 제목: “삭제 연산”var removed = list.remove(2); // remove by indexlist.remove("C"); // remove by valuevar first = list.shift(); // remove and return firstvar last = list.pop(); // remove and return lastvar spliced = list.splice(3); // remove from index to endlist.splice(2, 2); // remove 2 elements at index 2list.splice(1, 4, "start", 5, "end"); // remove 4, insert replacements수정 연산
섹션 제목: “수정 연산”list.set(3, "65"); // replace at indexlist[1] = "98"; // bracket assignmentlist.sort(); // ascending sort (default)list.sort(true); // ascendinglist.sort(false); // descendinglist.reverse(); // reverse in-placelist.fill(67); // fill entire listlist.fill(4, 1); // fill from index 1list.fill(2, 1, 4); // fill range [1, 4)원본을 바꾸지 않는 연산
섹션 제목: “원본을 바꾸지 않는 연산”다음 연산은 원본을 바꾸지 않고 새 리스트를 돌려줍니다.
var sorted = list.toSorted(); // new sorted list (ascending)var sortedDesc = list.toSorted(false); // new sorted list (descending)var reversed = list.toReversed(); // new reversed listvar sliced = list.slice(0, 2); // new sublist [0, 2)var replaced = list.with(1, 69); // new list with index 1 replacedvar merged = list.concat(otherList); // new concatenated listvar str = list.join(); // join elements into stringvar spliced = list.toSpliced(1, 0, "Feb"); // new list with splice appliedvar length = list.length();var memorySize = list.memorySize();var idx = list.indexOf("B", 1); // first index of "B" starting from 1list.validateClazzInArrayIsOnlyNumber(); // validate numeric contentisList(list); // type check → true수정할 수 없는 리스트
섹션 제목: “수정할 수 없는 리스트”var original = [];original.add(0x67);var unmodifiable = original.toUnmodifiable();unmodifiable.add(0x35); // throws error: List is unmodifiable세트는 중복을 허용하지 않는 순서 있는 컬렉션입니다.
var set1 = toSet(["B", "A", "C", "A"]); // from list (3 elements — "A" deduplicated)var set2 = createSet(); // empty setvar set3 = createSet(["A", "B", "C"]); // from listvar set4 = newSet(); // empty setforeach (item : set) { // process item}
var arr = set.toArray();for (var i = 0; i < set.size; i++) { var item = arr[i];}set.add(35); // add single element (returns true if new)set.addAll(otherSet); // merge another setset.remove(4); // remove elementset.clear(); // remove all elementsset.contains("A"); // membership check → true/falseset.size(); // element countset.toArray(); // convert to arrayset.toList(); // convert to listset.clone(); // shallow copyisSet(set); // type check → trueset.sort(); // ascending in-placeset.sort(true); // ascending in-placeset.sort(false); // descending in-placevar sorted = set.toSorted(); // new sorted set (ascending)var sortedDesc = set.toSorted(false); // new sorted set (descending)수정할 수 없는 세트
섹션 제목: “수정할 수 없는 세트”var original = createSet();original.add(0x67);var unmodifiable = original.toUnmodifiable();unmodifiable.add(0x35); // throws error: Set is unmodifiableTBEL은 기본형에만 배열을 지원합니다. 문자열 인덱싱은 문자를 돌려주고, 문자열 배열은 자동으로 리스트로 바뀝니다.
var array = new int[3];array[0] = 1;array[1] = 2;array[2] = 3;
var str = "My String";var ch = str[0]; // 'M'
isArray(array); // true사용자 지정 함수 예:
function sum(list) { var result = 0; for (var i = 0; i < list.length; i++) { result += list[i]; } return result;}var total = sum(array); // 6리터럴
섹션 제목: “리터럴”문자열
섹션 제목: “문자열”작은따옴표나 큰따옴표:
"This is a string literal"'This is also string literal'이스케이프 시퀀스: \\, \n, \r, \u#### (유니코드), \### (8진수).
125 // decimal integer0353 // octal0xAFF0 // hexadecimal10.503 // double94.92d // explicit double14.5f // float104.39484B // BigDecimal8.4I // BigInteger불리언과 null
섹션 제목: “불리언과 null”truefalsenullnil // alias for nullJava 클래스 사용
섹션 제목: “Java 클래스 사용”TBEL에서는 java.util과 java.lang의 Java 클래스를 제한적으로 쓸 수 있습니다.
var foo = Math.sqrt(4); // 2.0숫자 형식 변환
섹션 제목: “숫자 형식 변환”Integer.toString()으로 숫자를 16진수, 8진수, 2진수로 바꿉니다.
var b16 = Integer.toString(0x1A, 16); // "1a"var b10 = Integer.toString(0x1A, 10); // "26"var b8 = Integer.toString(0x1A, 8); // "32"var b2 = Integer.toString(0x1A, 2); // "11010"음수:
var i16 = Integer.toString(-255, 16); // "-ff"var i10 = Integer.toString(-255, 10); // "-255"var i8 = Integer.toString(-255, 8); // "-377"var i2 = Integer.toString(-255, 2); // "-11111111"float와 double의 16진수 문자열:
var f0 = 7823764.8374;var f16 = Float.toHexString(f0); // "0x1.dd8654p22"
var dd0 = 99993219.156013e-002;var dd16 = Double.toHexString(dd0); // "0x1.e83f862142b5bp19"long 변환:
var l16 = Long.toString(9223372036854775807, 16); // "7fffffffffffffff"var l10 = Long.toString(9223372036854775807, 10); // "9223372036854775807"var l8 = Long.toString(9223372036854775807, 8); // "777777777777777777777"var l2 = Long.toString(9223372036854775807, 2); // "111...111" (63 ones)보안 제약
섹션 제목: “보안 제약”Java 클래스의 새 인스턴스를 만들 수 없습니다.
java.util.Collections.reverse(list); // allowed — static method calllist = new java.util.ArrayList(); // NOT allowed — constructor callJSON 헬퍼
섹션 제목: “JSON 헬퍼”var metadataStr = JSON.stringify(metadata);var metadata = JSON.parse(metadataStr);흐름 제어
섹션 제목: “흐름 제어”If / else if / else
섹션 제목: “If / else if / else”if (temperature > 0) { return "Greater than zero!";} else if (temperature == -1) { return "Minus one!";} else { return "Something else!";}삼항 연산자
섹션 제목: “삼항 연산자”temperature > 0 ? "Yes" : "No";Foreach
섹션 제목: “Foreach”var numbers = [1, 2, 3];var sum = 0;foreach (n : numbers) { sum += n;}문자열은 문자 단위로 반복할 수 있습니다.
foreach (c : "ABCDEFGHIJKLMNOPQRSTUVWXYZ") { // process each character}For 반복문
섹션 제목: “For 반복문”var sum = 0;for (var i = 0; i < 100; i++) { sum += i;}While과 until
섹션 제목: “While과 until”while (isTrue()) { doSomething();}
until (isFalse()) { doSomething();}Do while / do until
섹션 제목: “Do while / do until”do { x = something();} while (x != null);
do { x = something();} until (x == null);