Programming 언어/Skill

[SKILL 강좌] procedure (@rest @optional @key)

호드맨 2017. 2. 2. 09:06

procedure에 대해서 배워봅시다. 이론은 별거 없습니다. 함수 만들어주는 함수이지요!

# procedure

procedure(
   s_funcName(l_formalArglist)
   g_expr1 ...
)
=> s_funcName

#Description
# Defines a function using a formal argument list. The body of the procedure is a list of
# expressions to evaluate. The body of the procedure is a list of expressions to be evaluated
# one after another when s_funcName is called. There must be no white space between procedure
# and the open parenthesis that follows, nor between s_funcName and the open parenthesis of
# l_formalArglist. However, for defun there must be white space between s_funcName and the
# open parenthesis. This is the only difference between the two functions. defun has been
# provided principally so that you can make your code appear more like other LISP dialects.
#
# The last argument in l_formalArglist can be a string denoting type-checking characters,
# specified using the argument type template. For more information about specifying the 
# argument type template, see Type Checking in Cadence SKILL Language User Guide.
#
# Expressions within a function can reference any variable on the formal argument list or any
# global variable defined outside the function. If necessary, local variables can be declared
# using the let or prog functions.

 

간단히 예제를 들어봅시다. 변수 a b를 더해주는 합수입니다. 함수를 define 하겠습니다.

procedure(jhAdd(a b)
   prog(()
      return(a+b)
   ); end prog
); end procedure

jhAdd

 

네 jhAdd라는 함수가 정의되었네요. a b라는 변수를 받아서 더한 다음 return 해줍니다. 함수 콜은 아시다시피 이렇게~

jhAdd(3 5)
8

 

자 procedure는 별거 없지만 사실 몇 가지 option 이 있습니다. cadence help에도 잘 나와있지만 @rest, @optional, @key를 알아봅시다.

위에 작성한 jhAdd 와는 좀 다른 상황이 되어서 변수 3개를 더해야 합니다. 그러면 변수가 3개인 procedure를 작성해야 하죠. 또 4개를 더할 때는 4개의 변수를 받아 더해주는 함수를 작성해야 합니다. 같은 기능인데 너무 번거로우니 @rest 옵션을 이용해봅시다.

# @rest

procedure(jhAdd(@rest a)
   prog(()
      sum=0
      foreach(num a
         sum=sum+num
      ); end foreach
      return(sum)
   ); end prog
); end procedure

> function jhAdd redefined
jhAdd

jhAdd('3 '3 '3 '5)
14
jhAdd('2 '8)
10

@rest 옵션을 사용할 경우 몇 개인지 모르는 변수를 받아 a라는 변수에 list로 저장해 줍니다. 이 list를 foreach 문을 이용해 모두 더해서 sum이라는 곳에 저장 후 return 한 것입니다. 뭔가 작성한 skill 이 범용적으로 사용될 때 쓰이지만 제가 작성한 skill 들은 개인적으로 사용하는 경우가 많아서 그다지 쓰인 적은 없네요.

 

뭔가 또 다른 상황입니다. 거의 대부분 주어진 숫자에 3을 더하는데 가끔~ 다른 수를 더할 때도 있습니다. 변수 2개 받기가 귀찮아요~ 이럴 때 @optional을 사용합니다. startFinder를 통해 함수를 찾아볼 때 변수가 [ ] 안에 있는 경우가 @optional로 지정된 경우입니다. 이렇게 숫자를 더하거나 할 경우는 별로 없고, cellView 등을 입력받을 때 대부분 current CellView를 입력받는 경우가 있어 그럴 때 사용되죠.

# @optional

procedure(jhAdd(a @optional (b 3))
   prog(()
      return(a+b)
   ); end prog
); end procedure

> function jhAdd redefined
jhAdd
 

jhAdd(6)
9
jhAdd(6 5)
11

 

아래의 결과처럼 변수를 1개만 줬을 경우엔 기본값인 3을 더해주고 변수를 2개 줬을 경우 둘을 더해줍니다. @optional (b 3) 은 b가 입력되지 않았을 경우 default value로 3을 주게 되는 거죠.

Finder에서 cdfCreateParam이라는 함수를 찾아보았습니다. 앞에서 @optional을 사용하면 [ ] 안에 변수가 있는데.. 여기서는 변수 이름에? 가 붙어 있네요.

# @key

cdfCreateParam( g_cdfDataId ?name t_name ?type t_type [?defValue g_defValue] 
   [?units t_units] 
   [?parseAsNumber t_parseAsNumber] 
   [?choices l_choices] 
   [?prompt t_prompt] 
   [?use t_use] 
   [?display t_display] 
   [?editable t_editable] 
   [?dontSave t_dontSave] 
   [?callback t_callback] 
   [?storeDefault t_storeDefault])
   [?parseAsCEL t_parseAsCEL] 
 )
     => cdfDataId / nil

 

keyword를 사용한 겁니다. 어떠한 함수를 정하는데 변수가 10개 20개 될 때 순서를 다 기억하기 힘들고 상황에 따라 어떠한 값은 default 값을 넣어주고 안 넣어 주고 하는 경우가 있습니다. 이럴 때 @key 옵션을 사용합니다. 알기 쉽게 예제로

procedure(jhAdd(@key (a 3) (b 5) c)
   prog(()
      return(a+b+c)
   ); end prog
); end procedure

> function jhAdd redefined
jhAdd


jhAdd(?c 5 ?a 4)
14
jhAdd(?c 1)
9

 

예제에는 변수를 3개만 넣었지만 실제로 복잡한 코딩을 하다 보면 변수가 7~8개 될 경우도 생깁니다. 이럴 때 유용하지요. 예전에 Basic Eng 님 요청으로 작성했던 createLabel.il 이 @key 옵션을 사용했습니다.

 

덧 1 : 코드를 약간 수정해 봤습니다. 변수 c는 default value를 안 넣어주었으니 항상 값을 입력받아야 합니다. 그리고 @key 옵션을 사용한 경우 변수의 입력 순서는 상관이 없습니다.

 

procedure는 당연히 기본적인 것이지만 @rest @optional @key는 옵션으로 유용하게 쓰일 곳이 있을 겁니다. 이런 기능이 있다는 것을 알아만 놓고 나중에 필요할 때 다시 보면 되지요. 다음엔 LSW window 관련 함수를 을 몇 개 살펴보겠습니다~