Es posible hacer nada después de una coincidencia de patrón en un foreach declaración?

Quiero hacer un post partido paso por ejemplo, para definir una variable. También quiero forzar un retorno de la Unidad como mi foreach es String => la Unidad, y por defecto Scala quiere volver a la última declaración.

Aquí está el código:

    Iteratee.foreach[String](_ match {
      case "date" => out.push("Current date: " + new Date().toString + "<br/>")
      case "since" => out.push("Last command executed: " + (ctm - last) + "ms before now<br/>")
      case unknow => out.push("Command: " + unknown + " not recognized <br/>")
    } //here I would like to set "last = ctm" (will be a Long) 
    ) 

ACTUALIZADO:
Nuevo código y contexto. También nuevas preguntas añadidas 🙂 Que están integrados en los comentarios.

def socket = WebSocket.using[String] { request =>

 //Comment from an answer bellow but what are the side effects?
 //By convention, methods with side effects takes an empty argument list
 def ctm(): Long = System.currentTimeMillis

 var last: Long = ctm

 //Command handlers
 //Comment from an answer bellow but what are the side effects?
 //By convention, methods with side effects takes an empty argument list
 def date() = "Current date: " + new Date().toString + "<br/>"
 def since(last: Long) = "Last command executed: " + (ctm - last) + "ms before now<br/>"
 def unknown(cmd: String) = "Command: " + cmd + " not recognized <br/>"

 val out = Enumerator.imperative[String] {}

 //How to transform into the mapping strategy given in lpaul7's nice answer.
 lazy val in = Iteratee.foreach[String](_ match {
   case "date" => out.push(date)
   case "since" => out.push(since(last))
   case unknown => out.push(unknown)
 } //Here I want to update the variable last to "last = ctm"
 ).mapDone { _ =>
   println("Disconnected")
 }

 (in, out)
}
InformationsquelleAutor Farmor | 2012-07-03

2 Comentarios

  1. 14

    No sé lo que su ctm es, pero siempre se puede hacer esto:

    val xs = List("date", "since", "other1", "other2")
    
    xs.foreach { str =>
    
        str match {
            case "date"  => println("Match Date")
            case "since" => println("Match Since")
            case unknow  => println("Others")
        } 
    
        println("Put your post step here")
    }

    Nota debe utilizar la {} en lugar de () cuando se desea utilizar un bloque de código como el argumento de un foreach().

    • Uno puede hacer aún más fácil: xs foreach { case "date" => .... }
  2. 3

    No voy a responder a su pregunta, pero debo señalar que la reasignación de las variables en Scala es una mala práctica. Le sugiero que vuelva a escribir su código para evitar vars.

    Primero, transformar las cadenas de algo más:

    val strings = it map {
      case "date" => "Current date: " + new Date().toString + "<br/>"
      case "since" => "Last command executed: " + (ctm - last) + "ms before now<br/>"
      case unknow => "Command: " + unknown + " not recognized <br/>"
    }

    Siguiente, empuje

    strings map { out.push(_) }

    Parece que la implementación de push tiene efectos secundarios. Malo para usted, debido a que estos métodos hace que su programa impredecible. Usted puede evitar los efectos secundarios, haciendo push devolver una tupla:

    def push(s: String) = {
      ...
      (ctm, last)
    }

    Y usarla como:

    val (ctm, last) = out.push(str)

    Actualización:

    Por supuesto, los efectos secundarios son necesarios para que los programas de utilidad. Yo sólo significaba que los métodos en función de las variables externas son menos predecibles que puro uno, es difícil razonar sobre ella. Es más fácil para los métodos de prueba sin efectos secundarios.

    Sí, se debe preferir vals sobre vars, que hace que su programa sea más «funcional» y a los apátridas. Los apátridas son los algoritmos de los subprocesos y muy predecible.

    Parece que su programa es el estado de la naturaleza. Al menos, tratar de mantenerse como «funcional» y apátridas como usted puede 🙂

    Mi propuesta de solución del problema es:

    //By convention, methods with side effects takes an empty argument list
    def ctm(): Long = //Get current time
    
    //Command handlers
    def date() = "Current date: " + new Date().toString + "<br/>"
    def since(last: Long) = "Last command executed: " + (ctm() - last) + "ms before now<br/>"
    def unknown(cmd: String) = "Command: " + unknown + " not recognized <br/>"    
    
      //In your cmd processing loop
    
      //First, map inputs to responses
      val cmds = inps map {
        case "date"  => date()
        case "since" => since(last)
        case unk     => unknown(unk)
      }
    
      //Then push responses and update state
      cmds map { response =>
        out.push(response)
        //It is a good place to update your state
        last = ctm()
      }

    Es difícil probar esto sin el contexto de su código, por lo que debe ajustarse a sus necesidades de ti. Espero haber respondido a tu pregunta.

    • Gracias por tu respuesta. Sin embargo tengo un par de preguntas/comentarios. ¿En qué sentido te refieres a que tenga efectos secundarios, es malo? El único propósito de fuera.push es tener un efecto secundario más específicos escribir en el websocket. empuje hacer devolver una Unidad, ya que sólo empuja la Cadena a través de un socket, así que no puedo asignar la tupla allí. La recomendación de val en lugar de var es interesante. Mis habilidades funcionales pueden faltar y mucho agradezco su respuesta actualizada en este contexto. la última es una variable de instancia que debe contener el currentTimeInMillies del último comando señores: a través de la websocket. el mdl es un def
    • Sí, gracias, entiendo que el contexto es vago, actualizado mi respuesta para dar un contexto más amplio. Tu respuesta es excelente. Todavía no entiendo su significado de efectos secundarios, por ejemplo, ¿qué efecto secundario es la fecha de() de la causa? También mi Iteratee no soportan el mapa?
    • Dónde están tus Iteratee vienen? Intenta Iteratee.mapa? Hizo compilar, o darle un error?

Dejar respuesta

Please enter your comment!
Please enter your name here