简体   繁体   中英

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?

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM