[scala] @main method review

오현우·2022년 9월 10일
0

@main method란?

파이썬에서 name == main 과 유시한 흐름으로 진행되는 main 메소드를 리뷰하고자 한다.

만약 파이썬 main function을 정의하는 법에 대해 알고 싶다면 아래의 링크를 참조하자.
https://realpython.com/python-main-function/

스칼라 공식 사이트에서는 아래와 같이 설명 되어있다.
Adding a @main annotation to a method turns it into entry point of an executable program.

이말을 조금 직관적으로 풀어서 설명하자면, 아래와 같다.

우리가 프로그램을 동작시키는 시작점을 만드는 방법이다.

def foo = 42
def bar = "Hello"
@main def run() = println("Hello")

scala scala_file

Hyeon-Woo@Macbook ~/mycodes/scala % scala ./scala_practice/src/main/Hello.scala
Hello

정상적으로 해당 작업이 수행되는 것을 확인할 수 있다.

main 어노테이션을 사용하기전에

def foo = 42
def bar = "Hello"
class Main:
  @main def run() = println("Hello")

위의 코드를 실행시켜보면

method run cannot be a @main method since it cannot be accessed statically

공식 독스에서는 아래와 같이 설명한다.

A @main annotated method can be written either at the top-level (as shown), or inside a statically accessible object. In either case, the name of the program is in each case the name of the method, without any object prefixes.

위의 문구를 확인하면 정적으로 지정하지 않았기 때문에 실행이 되지 않기 때문에 우리는 object 를 활용해서 진행해야 한다고 되어있다.

때문에 아래와 같이 수정하여 주자.

def foo = 42
def bar = "Hello"
object example:
  @main def run() = println("Hello")

정상적으로 출력이 된다.

def foo = 42
def bar = "Hello"
object Main:
  object Run:
    @main def run() = println("Hello")

오브젝트 안에 오브젝트를 넣어도 정적으로 지정된 것이기 때문에 문제가 되지 않는다.

object 나 class 에 대해 깊게 알아보고 싶다면 아래를 참조하자.
https://docs.scala-lang.org/scala3/book/domain-modeling-tools.html

정리하자면 2가지로 요약할 수 있다.

  1. @main annotation indicate where the program start!
  2. only static methods can be annotated

Command line arguments!

프로그램을 실행하다보면 어떤 인수들을 넘겨줘야 할 때가 존재한다.

def foo = 42
def bar = "Hello"

@main def run(name: String): Unit = println(s"Hello ${name}")

scala hello.scala yourname을 통해 진행하자.

정상적으로 아래와 같이 출력되는 것을 볼 수 있다.

Command line arguments를 정리하자면 아래와 같다.

  • 메인 메소드에 파라미터는 프로그램의 파라미터가 된다.

추가적으로 한번에 여러개의 동일한 타입의 데이터를 받아야 하는 경우도 존재한다.

그러한 경우는 아래와 같이 사용해주면 된다.

별의 의미는 하나 이상의 파라미터가 등장할 수 있다는 이야기다.

@main def run(xs: Int*): Unit =
  println(s"The sum is ${xs.sum}")

scala hello.scala 1 2 3 4 5

Custom Argument Parsing

우리는 위와 같이 str, int 뿐만아니라 클래스 또한 아규먼트로 넣고 싶을 때도 있을 것이다.

그러한 경우 아래와 같이 진행해주면 된다.

import scala.util.CommandLineParser

given CommandLineParser.FromString[Customtype] with
  def fromString(value: String): Customtype =
    body
    

구체적으로 예시를 들면 아래와 같이 진행할 수 있다.

import scala.util.CommandLineParser

given CommandLineParser.FromString[Color] with
  def fromString(value: String): Color =
    Color.valueOf(value)

enum Color:
  case Red, Green, Blue

@main def run(color: Color): Unit =
  println(s"The color is ${color.toString}")

scala hello.scala Red 를 넣어주면
The color is Red 가 정상적으로 출력이 된다.

opt-out case

일단 우리가 정보를 다 받고자 하고 시작할 때는 응용을 다음과 같이 진행할 수 있다.

@main def run(args: String*): Unit = 
  parseProgramArguments(args)

참조

https://docs.scala-lang.org/scala3/book/methods-main-methods.html

profile
핵심은 같게, 생각은 다르게

0개의 댓글