Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between object with main() and extends App in scala

Tags:

scala

I'm working through ScalaInAction (book is still a MEAP, but code is public on github) Right now I'm in chapter 2 looking at this restClient: : https://github.com/nraychaudhuri/scalainaction/blob/master/chap02/RestClient.scala

First, I setup intelliJ with scala extensions and created a HelloWorld with main():

<ALL the imports>

object HelloWorld {
   def main(args: Array[String]) {
     <ALL the rest code from RestClient.scala>
   }
}

I get the following error when compiling:

scala: forward reference extends over defintion of value command
val httppost = new HttpPost(url)
                ^

I can fix this by moving the following lines around until the ordering is correct with relation to the def's

require( args.size >= 2, "You need at least two arguments to make a get, post, or delete request")

val command = args.head
val params = parseArgs(args)
val url = args.last

command match {
  case "post"    => handlePostRequest
  case "get"     => handleGetRequest
  case "delete"  => handleDeleteRequest
  case "options" => handleOptionsRequest
}

While browsing the github page, I found this: https://github.com/nraychaudhuri/scalainaction/tree/master/chap02/restclient

Which uses implements RestClient.scala using extends App instead of a main() method:

<All the imports>
object RestClient extends App {
   <All the rest of the code from RestClient.scala>
}

I then changed my object HelloWorld to just use extends App instead of implementing a main() method and it works without errors

Why does the main() method way of doing this generate the error but the extends App does not?

like image 607
TheBigS Avatar asked Oct 20 '25 17:10

TheBigS


1 Answers

Because main() is a method, and variable's in method could not be forward reference.

For example:

object Test {

   // x, y is object's instance variable, it could be forward referenced

   def sum = x + y // This is ok
   val y = 10    
   val x = 10

}

But code in a method could not forward referenced.

object Test {
    def sum = {
        val t = x + y // This is not ok, you don't have x, y at this point
        val x = 10
        val y = 20
        val z = x + y // This is ok
    }
}

In your case, if you copy paste all codes from RestClient.scala to main(), you will have the same issue because var url is declared after its usage in handlePostRequest.

like image 135
Brian Hsu Avatar answered Oct 22 '25 07:10

Brian Hsu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!