My use case has case classes something like
case class Address(name:String,pincode:String){
override def toString =name +"=" +pincode
}
case class Department(name:String){
override def toString =name
}
case class emp(address:Address,department:Department)
I want to create a DSL like below.Can anyone share the links about how to create a DSL and any suggestions to achieve the below.
emp.withAddress("abc","12222").withDepartment("HR")
Update: Actual use case class may have more fields close to 20. I want to avoid redudancy of code
I created a DSL using reflection so that we don't need to add every field to it.
Disclamer: This DSL is extremely weakly typed and I did it just for fun. I don't really think this is a good approach in Scala.
The last example is the equivalent of writing:
A way of writing DSLs in Scala and avoid parentheses and the dot is by following this pattern:
Here is the source:
I really don't think you need the builder pattern in Scala. Just give your case class reasonable defaults and use the
copy
method.i.e.:
You could also use an immutable builder:
If you want to avoid modifying the origin classes you can use implicit class, e.g.
then
import EmpExtensions
wherever you need these methodsYou could do
and use it as
emp.builder.withAddress("abc","12222").withDepartment("HR").build()
.You don't need optional fields,
copy
, or the builder pattern (exactly), if you are willing to have the build always take the arguments in a particular order:The idea here is that each
emp
parameter gets its own class which provides a method to get you to the next class, until the final one gives you anemp
object. It's like currying but at the type level. As you can see I've added an extra parameter just as an example of how to extend the pattern past the first two parameters.The nice thing about this approach is that, even if you're part-way through the build, the type you have so far will guide you to the next step. So if you have a
WithDepartment
so far, you know that the next argument you need to supply is a department name.