2012-02-07 21 views
6

Estoy creando una pequeña DSL Scala y me encuentro con el siguiente problema del que realmente no tengo una solución. Un pequeño ejemplo conceptual de lo que quiero lograr:Scala DSL: método de encadenamiento con métodos sin parámetros

(Compute 
write "hello" 
read 'name 
calc() 
calc() 
write "hello" + 'name 
) 

el código que define esta DSL es más o menos esto:

Object Compute extends Compute{ 
    ... 
implicit def str2Message:Message = ... 
} 
class Compute{ 
def write(msg:Message):Compute = ... 
def read(s:Symbol):Compute = ... 
def calc():Compute = { ... } 
} 

Ahora la pregunta: ¿Cómo puedo deshacerme de estos paréntesis después Calc ? ¿Es posible? ¿si es así, cómo? solo omitirlos en la definición no ayuda debido a errores de compilación.

Respuesta

3

bien, creo, he encontrado una solución aceptable ... i consigue ahora esto posible sintaxis

| write "hello" 
| read 'name 
| calc 
| calc 
| write "hello " + 'name 

utilizando un objeto denominado "|", soy capaz de escribir casi dsl que quería . normalmente, un ";" es necesario después de calc si no tiene parámetros. El truco aquí es aceptar el objeto DSL en sí (aquí, es el "|" en la siguiente línea). hacer este parámetro implícito también permite calc como último enunciado en este código. Bueno, parece que definitivamente no es posible tenerlo como yo quiero, pero esto también está bien

+0

¡Yay! ¡Difícil!))) – noncom

-1

Primero intente eliminar los paréntesis de la definición de calc. Segundo, intente usar llaves alrededor del todo en lugar de paréntesis. Las llaves y los paréntesis no significan lo mismo y creo que el paréntesis funciona mejor en el código de una sola línea (a menos que se utilicen puntos y comas). Consulte también What is the formal difference in Scala between braces and parentheses, and when should they be used?

+1

hay una razón para usar parantheses aquí. methodchaining realmente no funciona con líneas nuevas, excepto si está rodeado por "()" porque entonces Scala sabe, es solo una declaración. no funciona con "{}". dejar la parántesis de la definición de calc no funciona porque, entonces, el azúcar scala sintáctico ya no funciona y no puedo llamar en cadena a otro método – wrm

+0

Ah ... justo estaba pensando al revés. ¿Qué errores de compilación obtienes? ¿Puedes condensar tu ejemplo para ser ejecutable? – thoredge

+0

marca la última línea y dice: \t - falta de argumentos para la escritura de métodos en la clase Compute; siga este método con '_' si desea tratarlo como una función parcialmente aplicada \t - ')' esperado pero encontrado literal de símbolo. el problema aquí es que la conversión normal de 'x.y (p1) .z (p2)' a 'x y p1 z p2' no funciona, porque es más como' x.y.z (p2) 'que no se puede convertir evidentemente en azúcar.hay otras maneras de usar el método de encadenamiento para lograr algo similar, pero no puedo encontrar una forma de lograr esta sintaxis ... – wrm

3

No es posible deshacerse del paréntesis, pero puede reemplazarlo. Por ejemplo:

object it 

class Compute { 
def calc(x: it.type):Compute = { ... } 

(Compute 
write "hello" 
read 'name 
calc it 
calc it 
write "hello" + 'name 
) 

Para ampliar un poco, siempre Scala ve algo como esto:

object method 
non-reserved-word 

Se supone que significa object.method(non-reserved-word). Por el contrario, cada vez que ve algo como esto:

object method object 
method2 object2 

Se supone que son dos estados independientes, como en object.method(object); method2.object, esperando method2 a ser un objeto nuevo, y object2 un método.

Estas suposiciones son parte de la gramática de Scala: debe ser así a propósito.

+0

Acabo de llegar a una solución similar (teniendo calc tomar un parámetro) como escribí justo en este momento (ver mi respuesta). También probé varias otras formas, como una clase de caso o una llamada a un método estático, pero parece que esta es la única forma – wrm

+0

Si tiene algo de tiempo, ¿podría escribir por qué es imposible deshacerse del paréntesis? – kisileno

+0

Y otra pregunta es acerca de los paréntesis que rodean toda expresión, ¿podemos evitarlos y cómo? – kisileno

Cuestiones relacionadas