Call a method on the value of Scala Option if present












0















I am trying to figure out the best way to refactor the following code to eliminate the use of Option.get(). I know that using the get method is considered bad practice.



if (myConnection.isDefined) {
myConnection.get.close
}


where myConnection is of type Option[Connection]



getOrElse doesn't seem like it would work, because there is no "else" object to call the method on. If myConnection is None, then I don't want to do anything.



I suppose I could use forEach like:



myConnection.foreach{ c => c.close }


This would work, but it looks weird to me. In my case, myConnection would never contain more than one connection, and someone else later looking at my code might be led to believe that it could contain multiple connections.



Is there a better way to do this that is both concise and clear?










share|improve this question


















  • 2





    Using foreach is already concise and clear to an experienced Scala programmer, so don't worry about other programmers getting confused. I would write myConnection.foreach(_.close), but otherwise this is the natural way to write this code.

    – Tim
    Nov 21 '18 at 20:04











  • I agree, there is nothing to worry about. Foreach is just fine and you will get used to it too. Soon, you will find yourself writing future.foreach, knowing exactly what it means.

    – ygor
    Nov 21 '18 at 20:59


















0















I am trying to figure out the best way to refactor the following code to eliminate the use of Option.get(). I know that using the get method is considered bad practice.



if (myConnection.isDefined) {
myConnection.get.close
}


where myConnection is of type Option[Connection]



getOrElse doesn't seem like it would work, because there is no "else" object to call the method on. If myConnection is None, then I don't want to do anything.



I suppose I could use forEach like:



myConnection.foreach{ c => c.close }


This would work, but it looks weird to me. In my case, myConnection would never contain more than one connection, and someone else later looking at my code might be led to believe that it could contain multiple connections.



Is there a better way to do this that is both concise and clear?










share|improve this question


















  • 2





    Using foreach is already concise and clear to an experienced Scala programmer, so don't worry about other programmers getting confused. I would write myConnection.foreach(_.close), but otherwise this is the natural way to write this code.

    – Tim
    Nov 21 '18 at 20:04











  • I agree, there is nothing to worry about. Foreach is just fine and you will get used to it too. Soon, you will find yourself writing future.foreach, knowing exactly what it means.

    – ygor
    Nov 21 '18 at 20:59
















0












0








0


1






I am trying to figure out the best way to refactor the following code to eliminate the use of Option.get(). I know that using the get method is considered bad practice.



if (myConnection.isDefined) {
myConnection.get.close
}


where myConnection is of type Option[Connection]



getOrElse doesn't seem like it would work, because there is no "else" object to call the method on. If myConnection is None, then I don't want to do anything.



I suppose I could use forEach like:



myConnection.foreach{ c => c.close }


This would work, but it looks weird to me. In my case, myConnection would never contain more than one connection, and someone else later looking at my code might be led to believe that it could contain multiple connections.



Is there a better way to do this that is both concise and clear?










share|improve this question














I am trying to figure out the best way to refactor the following code to eliminate the use of Option.get(). I know that using the get method is considered bad practice.



if (myConnection.isDefined) {
myConnection.get.close
}


where myConnection is of type Option[Connection]



getOrElse doesn't seem like it would work, because there is no "else" object to call the method on. If myConnection is None, then I don't want to do anything.



I suppose I could use forEach like:



myConnection.foreach{ c => c.close }


This would work, but it looks weird to me. In my case, myConnection would never contain more than one connection, and someone else later looking at my code might be led to believe that it could contain multiple connections.



Is there a better way to do this that is both concise and clear?







scala scala-option






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 19:01









JoeMjr2JoeMjr2

1,59631938




1,59631938








  • 2





    Using foreach is already concise and clear to an experienced Scala programmer, so don't worry about other programmers getting confused. I would write myConnection.foreach(_.close), but otherwise this is the natural way to write this code.

    – Tim
    Nov 21 '18 at 20:04











  • I agree, there is nothing to worry about. Foreach is just fine and you will get used to it too. Soon, you will find yourself writing future.foreach, knowing exactly what it means.

    – ygor
    Nov 21 '18 at 20:59
















  • 2





    Using foreach is already concise and clear to an experienced Scala programmer, so don't worry about other programmers getting confused. I would write myConnection.foreach(_.close), but otherwise this is the natural way to write this code.

    – Tim
    Nov 21 '18 at 20:04











  • I agree, there is nothing to worry about. Foreach is just fine and you will get used to it too. Soon, you will find yourself writing future.foreach, knowing exactly what it means.

    – ygor
    Nov 21 '18 at 20:59










2




2





Using foreach is already concise and clear to an experienced Scala programmer, so don't worry about other programmers getting confused. I would write myConnection.foreach(_.close), but otherwise this is the natural way to write this code.

– Tim
Nov 21 '18 at 20:04





Using foreach is already concise and clear to an experienced Scala programmer, so don't worry about other programmers getting confused. I would write myConnection.foreach(_.close), but otherwise this is the natural way to write this code.

– Tim
Nov 21 '18 at 20:04













I agree, there is nothing to worry about. Foreach is just fine and you will get used to it too. Soon, you will find yourself writing future.foreach, knowing exactly what it means.

– ygor
Nov 21 '18 at 20:59







I agree, there is nothing to worry about. Foreach is just fine and you will get used to it too. Soon, you will find yourself writing future.foreach, knowing exactly what it means.

– ygor
Nov 21 '18 at 20:59














3 Answers
3






active

oldest

votes


















1














Typically, you would map over an Option to operate on its value.



myConnection.map(c => c.close())


or



myConnection.map(close(_))


which will do nothing if c is None and will return a None. Otherwise, it give you a Some(True) if, for example, close() returns a True when it succeeds. If close() had no return value, then mapping will return a Some(()) which has the type Option[Unit].






share|improve this answer































    3














    foreach makes sense when you are doing computation with return valueunit, side-effects. Closing a connection sounds good case for
    foreach to me.



    This is what Option.foreach looks like:



    @inline final def foreach[U](f: A => U) {
    if (!isEmpty) f(this.get)
    }


    But if you want to do some computation and return the value, .map or match could be better.



    import scala.util.Try

    val connectionMaybe = Try {
    DriverManager.getConnection(
    s"jdbc:h2:~/test;MODE=Oracle",
    "sa",
    ""
    )
    }.toOption


    def getSomething(connectionMaybe: Option[Connection]): Option[Int] = {
    connectionMaybe match {
    case Some(connection) =>
    val statement = connection.createStatement()
    val rs = statement.executeQuery(s"select * from something")
    Option(rs.getInt("some_column"))
    //cleanup if needed
    case _ =>
    println("no connection found")
    None
    }
    }





    share|improve this answer

































      0














      Pattern-matching version if you don't like pure functional foreach/map calls:



      myConnection match {
      case Some(conn) =>
      conn // TODO add logic here, `con` is unwrapped here
      case None =>
      // TODO add error-back logic here
      }





      share|improve this answer























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418910%2fcall-a-method-on-the-value-of-scala-option-if-present%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        1














        Typically, you would map over an Option to operate on its value.



        myConnection.map(c => c.close())


        or



        myConnection.map(close(_))


        which will do nothing if c is None and will return a None. Otherwise, it give you a Some(True) if, for example, close() returns a True when it succeeds. If close() had no return value, then mapping will return a Some(()) which has the type Option[Unit].






        share|improve this answer




























          1














          Typically, you would map over an Option to operate on its value.



          myConnection.map(c => c.close())


          or



          myConnection.map(close(_))


          which will do nothing if c is None and will return a None. Otherwise, it give you a Some(True) if, for example, close() returns a True when it succeeds. If close() had no return value, then mapping will return a Some(()) which has the type Option[Unit].






          share|improve this answer


























            1












            1








            1







            Typically, you would map over an Option to operate on its value.



            myConnection.map(c => c.close())


            or



            myConnection.map(close(_))


            which will do nothing if c is None and will return a None. Otherwise, it give you a Some(True) if, for example, close() returns a True when it succeeds. If close() had no return value, then mapping will return a Some(()) which has the type Option[Unit].






            share|improve this answer













            Typically, you would map over an Option to operate on its value.



            myConnection.map(c => c.close())


            or



            myConnection.map(close(_))


            which will do nothing if c is None and will return a None. Otherwise, it give you a Some(True) if, for example, close() returns a True when it succeeds. If close() had no return value, then mapping will return a Some(()) which has the type Option[Unit].







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 21 '18 at 19:15









            MetropolisMetropolis

            1,206927




            1,206927

























                3














                foreach makes sense when you are doing computation with return valueunit, side-effects. Closing a connection sounds good case for
                foreach to me.



                This is what Option.foreach looks like:



                @inline final def foreach[U](f: A => U) {
                if (!isEmpty) f(this.get)
                }


                But if you want to do some computation and return the value, .map or match could be better.



                import scala.util.Try

                val connectionMaybe = Try {
                DriverManager.getConnection(
                s"jdbc:h2:~/test;MODE=Oracle",
                "sa",
                ""
                )
                }.toOption


                def getSomething(connectionMaybe: Option[Connection]): Option[Int] = {
                connectionMaybe match {
                case Some(connection) =>
                val statement = connection.createStatement()
                val rs = statement.executeQuery(s"select * from something")
                Option(rs.getInt("some_column"))
                //cleanup if needed
                case _ =>
                println("no connection found")
                None
                }
                }





                share|improve this answer






























                  3














                  foreach makes sense when you are doing computation with return valueunit, side-effects. Closing a connection sounds good case for
                  foreach to me.



                  This is what Option.foreach looks like:



                  @inline final def foreach[U](f: A => U) {
                  if (!isEmpty) f(this.get)
                  }


                  But if you want to do some computation and return the value, .map or match could be better.



                  import scala.util.Try

                  val connectionMaybe = Try {
                  DriverManager.getConnection(
                  s"jdbc:h2:~/test;MODE=Oracle",
                  "sa",
                  ""
                  )
                  }.toOption


                  def getSomething(connectionMaybe: Option[Connection]): Option[Int] = {
                  connectionMaybe match {
                  case Some(connection) =>
                  val statement = connection.createStatement()
                  val rs = statement.executeQuery(s"select * from something")
                  Option(rs.getInt("some_column"))
                  //cleanup if needed
                  case _ =>
                  println("no connection found")
                  None
                  }
                  }





                  share|improve this answer




























                    3












                    3








                    3







                    foreach makes sense when you are doing computation with return valueunit, side-effects. Closing a connection sounds good case for
                    foreach to me.



                    This is what Option.foreach looks like:



                    @inline final def foreach[U](f: A => U) {
                    if (!isEmpty) f(this.get)
                    }


                    But if you want to do some computation and return the value, .map or match could be better.



                    import scala.util.Try

                    val connectionMaybe = Try {
                    DriverManager.getConnection(
                    s"jdbc:h2:~/test;MODE=Oracle",
                    "sa",
                    ""
                    )
                    }.toOption


                    def getSomething(connectionMaybe: Option[Connection]): Option[Int] = {
                    connectionMaybe match {
                    case Some(connection) =>
                    val statement = connection.createStatement()
                    val rs = statement.executeQuery(s"select * from something")
                    Option(rs.getInt("some_column"))
                    //cleanup if needed
                    case _ =>
                    println("no connection found")
                    None
                    }
                    }





                    share|improve this answer















                    foreach makes sense when you are doing computation with return valueunit, side-effects. Closing a connection sounds good case for
                    foreach to me.



                    This is what Option.foreach looks like:



                    @inline final def foreach[U](f: A => U) {
                    if (!isEmpty) f(this.get)
                    }


                    But if you want to do some computation and return the value, .map or match could be better.



                    import scala.util.Try

                    val connectionMaybe = Try {
                    DriverManager.getConnection(
                    s"jdbc:h2:~/test;MODE=Oracle",
                    "sa",
                    ""
                    )
                    }.toOption


                    def getSomething(connectionMaybe: Option[Connection]): Option[Int] = {
                    connectionMaybe match {
                    case Some(connection) =>
                    val statement = connection.createStatement()
                    val rs = statement.executeQuery(s"select * from something")
                    Option(rs.getInt("some_column"))
                    //cleanup if needed
                    case _ =>
                    println("no connection found")
                    None
                    }
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 21 '18 at 19:25

























                    answered Nov 21 '18 at 19:19









                    prayagupdprayagupd

                    19.6k890137




                    19.6k890137























                        0














                        Pattern-matching version if you don't like pure functional foreach/map calls:



                        myConnection match {
                        case Some(conn) =>
                        conn // TODO add logic here, `con` is unwrapped here
                        case None =>
                        // TODO add error-back logic here
                        }





                        share|improve this answer




























                          0














                          Pattern-matching version if you don't like pure functional foreach/map calls:



                          myConnection match {
                          case Some(conn) =>
                          conn // TODO add logic here, `con` is unwrapped here
                          case None =>
                          // TODO add error-back logic here
                          }





                          share|improve this answer


























                            0












                            0








                            0







                            Pattern-matching version if you don't like pure functional foreach/map calls:



                            myConnection match {
                            case Some(conn) =>
                            conn // TODO add logic here, `con` is unwrapped here
                            case None =>
                            // TODO add error-back logic here
                            }





                            share|improve this answer













                            Pattern-matching version if you don't like pure functional foreach/map calls:



                            myConnection match {
                            case Some(conn) =>
                            conn // TODO add logic here, `con` is unwrapped here
                            case None =>
                            // TODO add error-back logic here
                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 21 '18 at 20:47









                            morsikmorsik

                            699815




                            699815






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418910%2fcall-a-method-on-the-value-of-scala-option-if-present%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Wiesbaden

                                Marschland

                                Dieringhausen