반응형
< 출처: http://javaora.tistory.com/entry/Learning-the-JavaFX-Script-Programming-Language-Lesson-2-Writing-Scripts >
본 글은 Learning the JavaFX Script Programming Language - Lesson 2: Writing Scripts 를 옮겨 작성한 글 입니다.
본 글은 Learning the JavaFX Script Programming Language - Lesson 2: Writing Scripts 를 옮겨 작성한 글 입니다.
- 간단한 계산기 작성
- 스크립트 변수 선언
- 스크립트 함수 정의 및 호출
- 스크립트 함수에 인자 넘기기
- 스크립트 함수의 리턴 값
- Command-Line 인자 접근
* 간단한 계산기 작성
에디터를 열고 아래 코드를 입력한다.
def numOne = 100; def numTwo = 2; var result; add(); subtract(); multiply(); divide(); function add() { result = numOne + numTwo; println("{numOne} + {numTwo} = {result}"); } function subtract() { result = numOne - numTwo; println("{numOne} - {numTwo} = {result}"); } function multiply() { result = numOne * numTwo; println("{numOne} * {numTwo} = {result}"); } function divide() { result = numOne / numTwo; println("{numOne} / {numTwo} = {result}"); }
컴파일과 실행은 자바와 유사함을 알 수 있다.
* 스크립트 변수 선언
이제 calculator.fx 를 자세히 들여다 보자.(차후 이 예제를 확장 할 것이다.)
코드의 첫번째 부분은 변수의 선언으로 시작된다.
def numOne = 100;
def numTwo = 2;
var result;
def numTwo = 2;
var result;
스크립트의 변수 선언엔 var 와 def 키워드 두가지가 사용된다. var 는 스크립트 전체에 통해 계속적으로 새로운 값을 할당 할 때 사용하며(그야말로 진정한 변수이다.), def 는 변수 선언 처음에 값을 할당하여 상수로서 사용되어진다.
위 코드에서도 계속적으로 사용되어질 상수와 같은 값은 def 로 선언하고 초기값을 할당하였고, 매 계산시 마다 값을 저장할 result 는 var 로 선언하고 초기화하지 않음을 알 수 있다.
우리는 result 변수에 숫자만 들어간다는 타입설정을 하지 않았음에도 컴파일시 문제가 없다. 이는 컴파일러가 사용자가 작성한 코드상의 변수의 사용을 보고 그 의도를 파악하여 자동으로 타입을 계산(추측) 해낸다. 이를 형 추론(Type Inference)라 한다. 이 형 추론은 스크립트 프로그래머에게 데이터 타입 선언이라는 짐을 덜어주므로서 당신의 일을 좀 더 쉽게 해준다.
* 스크립트 함수 정의 및 호출
소스의 남은 부부은 두 숫자의 덧셈/뺄셈/곱셈/나눗셈 의 스크립트 함수를 정의한다.
function add() {
result = numOne + numTwo;
println("{numOne} + {numTwo} = {result}");
}
...
result = numOne + numTwo;
println("{numOne} + {numTwo} = {result}");
}
...
함수는 특정 업무를 수행하는 실행가능한 코드의 블럭이다. 이 예에서 각 함수는 4칙연산중 하나를 수행하고 그 결과를 프린트 한다. 함수로 코드를 구조화(블럭화) 하는 것은 일반적인 것으로서 이는 프로그램을 읽기 쉽고, 쓰기 쉽고, 디버그 하기 쉽게 만들어 준다. 함수의 몸체(body)부분은 중괄호(brace)를 이용해 시작과 끝을 나내 가독성을 높인다.
함수는 명시적으로 호출(invoke)되기 전까지 실행되지 않는다. 이는 스크립트상 어느 위치에서든 함수가 실행 가능하게 만든다. 함수를 호출하는 것은 함수를 선언하기 전이든 후든 큰 문제가 되지 않는다. 위 예제에서도 함수가 실제 소스코드상에 선언되기 전 호출되어지고 있다.
함수의 호출은 아래와 같다.
add();
subtract();
multiply();
divide();
subtract();
multiply();
divide();
* 스크립트 함수에 인자 넘기기
다음으로 이전의 calculator.fx 의 함수를 인자(arguments)를 받도록 수정 해보자. 인자는 함수를 호출하면서 함수로 넘기는 특정 값(specific value)이다. 이 수정으로 위 사칙연산 함수는 하드코딩된 고정된 값이 아닌 어떤 임의의 두 숫자라도 계산을 할 수 있게 해준다.
var result; add(100,10); subtract(50,5); multiply(25,4); divide(500,2); function add(argOne: Integer, argTwo: Integer) { result = argOne + argTwo; println("{argOne} + {argTwo} = {result}"); } function subtract(argOne: Integer, argTwo: Integer) { result = argOne - argTwo; println("{argOne} - {argTwo} = {result}"); } function multiply(argOne: Integer, argTwo: Integer) { result = argOne * argTwo; println("{argOne} * {argTwo} = {result}"); } function divide(argOne: Integer, argTwo: Integer) { result = argOne / argTwo; println("{argOne} / {argTwo} = {result}"); }
컴파일 후 재실행 한 결과는 아래와 같다.
위 코드에는 제일 위에 정의된 numOne 과 numTwo 변수가 더 이상 필요가 없어 삭제되었다. 대신 함수에 정의된 인자를 통해 두 숫자를 넘겨 받도록 수정 되었다. 각 인자는 각각의 이름과 콜론(:) 로 구분된 타입으로 나타내진다. 하나 이상의 인자는 콤마(,)로 구분한다.
* 스크립트 함수의 리턴 값
함수는 선택적으로 값을 함수를 호출한 코드로 리턴할 수 있다. 예를 들면, add 함수의 결과 값이 리턴되도록 수정 되어질 수도 있다. - Bold 표시 참고
function add(argOne: Integer, argTwo: Integer) : Integer {
result = argOne + argTwo;
println("{argOne} + {argTwo} = {result}");
return result;
}
result = argOne + argTwo;
println("{argOne} + {argTwo} = {result}");
return result;
}
이 add 함수는 아래와 같이 사용한다.
var total;
total = add(1,300) + add(23,52);
total = add(1,300) + add(23,52);
리턴되는 값이 없는 경우 함수는 default 로 Void 를 리턴한다.
* Command-Line 인자 접근
우리는 위 코드를 command-line 인자를 받아들이도록 수정 할 수도 있다. 이를 통해 런타임시 계산되는 숫자를 입력 할 수 있다.
var result; function run(args : String[]) { // Strings 을 Integers 로 변환 def numOne = java.lang.Integer.parseInt(args[0]); def numTwo = java.lang.Integer.parseInt(args[1]); // 함수 호출 add(numOne,numTwo); subtract(numOne,numTwo); multiply(numOne,numTwo); divide(numOne,numTwo); } function add(argOne: Integer, argTwo: Integer) { result = argOne + argTwo; println("{argOne} + {argTwo} = {result}"); } function subtract(argOne: Integer, argTwo: Integer) { result = argOne - argTwo; println("{argOne} - {argTwo} = {result}"); } function multiply(argOne: Integer, argTwo: Integer) { result = argOne * argTwo; println("{argOne} * {argTwo} = {result}"); } function divide(argOne: Integer, argTwo: Integer) { result = argOne / argTwo; println("{argOne} / {argTwo} = {result}"); }
위 소스를 보면 눈에 띄는 점이 있는데 바로 run() 함수 블럭의 추가이다. 이 run() 함수는 일반적인 함수와는 다른 특별한 함수로 모든 스크립트의 시작점이 된다.(Java의 main() 함수와 같은 역할을 한다.) run() 함수는 모든 command-line 인자를 args 라는 String 형의 시퀀스(Sequence)에 저장해두고 있다.(Sequence는 순서가 있는 리스트로서 다른 언어의 배열과 비슷하다. 시퀀스는 세부적으로 Expressions 와 Operators로 나뉜다. - Lesson 6과 7 에서 상세히 설명함.)
이 스크립트를 실행하려면, 계산하려는 두 숫자를 런타임시 입력해야 한다. 실행 결과는 아래와 같다.
이번 소스에도 numOne과 numTwo 변수가 있다. 하지만 이번에 변수의 Scope는 run() 메소드 안으로 제한된다. 이 calculator 함수는 숫자를 인자로 받으므로 String 형식의 command-line 인자를 Integer로 컨버팅 한다. 이때 Java API의 도움을 받아 형변환을 수행한다.
run() 함수는 명시적으로 입력하지 않더라도 컴파일러가 컴파일시 자동으로 run() 함수를 생성한다. 마치 자바의 생성자 처럼 말이다. 따라서 컴파일된 bytecode 상에선 run() 함수를 명시한것과 명시하지 않을 것 사이의 큰 차이는 없다.