fmo
fmo

Reputation: 818

Custom method signature in a scala dsl

Is there a way to create a scala dsl which enables me to write code similar to this pseudo-code

edited: changed to scala pseudo code

object AccessProtectedClass extends App{
   def protectedMethod(param:String)
     permit_if (param.startsWith("asdf") and RAM <= 10) : Int = {
         var result = 10
         //do something
         return result;
   } 
}

If the access is not granted due to the 'permit if' statement a exception should be thrown. Which scala concepts do I need?

Upvotes: 1

Views: 152

Answers (3)

R&#233;gis Jean-Gilles
R&#233;gis Jean-Gilles

Reputation: 32719

If I understand correctly, basically the permit_if method just takes a condition and a block of code, and throws an exception of the condition is not met. This is trivially implemented as follows:

def permit_if[T]( condition: Boolean )( f: => T ): T = {
  if ( condition ) f
  else throw new Exception("Permit conditions not met!")
}

You would use it like this:

object AccessProtectedClass extends App{
   def protectedMethod( param:String ): Int = 
     permit_if (param.startsWith("asdf") && RAM <= 10)  {
         var result = 10
         //do something
         return result;
   } 
}

In fact the standard library already contains a method require to check requirements, so unless you need to throw a very specific exception, you might just use that. Just replace permit_if with require in the above code snippet and that's it.

Upvotes: 1

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297265

It is possible to write code similar to this. There are two things you have to keep in mind:

  • Scala infix notation follows the pattern obj method param method param method param..., so you have to place keywords for method names at the proper places.
  • Operator precedence can help you or hinder you. For example, <= has greater precedence than and, which will help with the snippet you've shown. So does dot notation. Parenthesis following an object also gets a higher precedence as the apply method on that object, which Specs2, for instance, puts to good use.

So, back to this:

permit if param.startsWith("xyz") and CPU <= 50 { ... }

We can break it like this:

permit // object
if     // method, though "if" is a reserved word, so you have to pick something else
param.startsWith("xyz") // param, because of higher precedence
and    // method
CPU <= 50 // param, because of higher precedence
// method needed here!
{ ... } // param

So it looks to me as if the builder pattern will work here, with minor adjustments. The parameter to and (or any or) will probably be by-name, so you can avoid evaluation of latter conditions if the result is defined by the former ones.

Upvotes: 3

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369526

Scala DSLs are valid Scala code. What you posted isn't. Therefore, it's not possible.

Upvotes: -1

Related Questions