Calling Method in Scala from User Input - scala

I have a user input:
val method = """doReplace(doReplace("ab","a","x"),"b","y")"""
How can I invoke this method at run-time using Scala:
object test2 {
def doReplace(str: String, oldChar: String, newChar: String) = {
str.replace(oldChar, newChar)
}
def main(args: Array[String]): Unit = {
val method = """doReplace(doReplace("ab","a","x"),"b","y")"""
}
}

If the user should only be able to call certain methods or have a simple grammar, you may write a simple parser that uses reflection. Scala fastparse is a really great utilty.
If the user should be able to enter arbitrary scala code, you could use a scala implementation of the JSR 223 scripting api or you can compile the code at runtime as describe in this question.
Be aware that this allows to execute arbitrary code on your machine. Do not expose this interface.

Related

Unable to run a Scala class in Intellij 15

I am very new to Scala. I am using IntelliJ IDE to run a very simple program in Scala(2.11.7).
My program goes like
class Rational(n:Int,d:Int) {
val oneHalf = new Rational(1,2)
}
I am trying to run it as a Class rather than a object. How could I Run this class in IntelliJ?
Thanks
As #Clashsoft says you can not initialize the class like this. You can do some thing simple like this for testing:
class Rational(n: Int, d: Int) {
def oneHalf: Int =
n * d
}
object MyProgram {
def main(args: Array[String]) {
val rational = new Rational(1, 2)
println(rational.oneHalf)
}
}
It is also possible to use App trait (extends App) then you do not need to have main method:
object MyProgram extends App {
val rational = new Rational(1, 2)
println(rational.oneHalf)
}
All depends on how you want to implement your solution at the end. Regarding different between main and App trait please read more.
Thx to #tzachzohar for following addition:
In Scala, just like in Java, only a static main method (with appropriate argument and return types) can serve as a program's entry point. For convenience, IntelliJ IDEA provides a Scala Worksheet as a way to easily test your code, but that's no magic either - it's a just nice wrapper - behind the scenes, a worksheet has its own main method calling your code.

Best Practice to Load Class in Scala

I'm new to Scala (and functional programming as well) and I'm developing a plugin based application to learn and study.
I've cretead a trait to be the interface of a plugin. So when my app starts, it will load all the classes that implement this trait.
trait Plugin {
def init(config: Properties)
def execute(parameters: Map[String, Array[String]])
}
In my learning of Scala, I've read that if I want to program in functional way, I should avoid using var. Here's my problem:
The init method will be called after the class being loaded. And probably I will want to use the values from the config parameter in the execute method.
How to store this without using a var? Is there a better practice to do what I want here?
Thanks
There is more to programming in a functional way than just avoiding vars. One key concept is also to prefer immutable objects. In that respect your Plugin API is already breaking functional principles as both methods are only executed for their side-effects. With such an API using vars inside the implementation does not make a difference.
For an immutable plugin instance you could split plugin creation:
trait PluginFactory {
def createPlugin (config: Properties): Plugin
}
trait Plugin {
def execute ...
}
Example:
class MyPluginFactory extends MyPlugin {
def createPlugin (config: Properties): Plugin = {
val someValue = ... // extract from config
new MyPlugin(someValue)
}
}
class MyPlugin (someValue: String) extends Plugin {
def execute ... // using someConfig
}
You can use a val! It's basically the same thing, but the value of a val field cannot be modified later on. If you were using a class, you could write:
For example:
class Plugin(val config: Properties) {
def init {
// do init stuff...
}
def execute = // ...
}
Unfortunately, a trait cannot have class parameters. If you want to have a config field in your trait, you wont be able to set its value immediately, so it will have to be a var.

Scala testing Mailer.sendEmailClientSuspended

I have the following bit of code below and need to test the email is sent when a user is suspended.
def suspendClient(client: Client, event: Event): EventResult = {
Logger.debug(String.format(s"Found Client[${client.getName}]"));
subService.suspend(client)
Mailer.sendEmailClientSuspended(client)
WebHookEventDAO.completeEvent(event.getId)
EventResult.ok
}
The main bit of logic i'm trying to test is Mailer.sendEmailClientSuspended(client) is invoked with the correct args e.g the correct Client is passed. Is it worth splitting it up into a seperate function and how difficult is it to test a 'Object' in Scala since Mailer is an Object.
Assuming you're writing your tests in Scala with MockitoSugar and ScalaTest you want to be using an ArgumentCaptor from the Mockito library. This allows you to capture the value of the client object passed as the parameter to the fundtion sendEmailClientSuspended(client).
See this stackoverflow post for a worked example you can follow. You'll need to specify the package your Client class is in, so something like this...
val capturedClient = ArgumentCaptor.forClass(classOf[com.acme.app.Client])
If your Mailer object doesn't extent a Trait currently, add one so you can mock the Trait and call verify() on it.
If you don't own the code to Mailer, you can move the call out into it's own helper class that you write, and you can then mock the new Trait. Something like this...
trait MailerTrait {
def sendEmailClientSuspended(client: Client): Unit
}
object MyMailer extends MailerTrait () {
def sendEmailClientSuspended(client: Client): Unit = {
Mailer.sendEmailClientSuspended(client)
}
}

Can I define and use functions outside classes and objects in Scala?

I begin to learn Scala and I'm interesting can I define and use function without any class or object in Scala as in Haskell where there is no OOP concept. I'm interested can I use Scala totally without any OOP concept?
P.S. I use IntelliJ plugin for Scala
Well, you cannot do that really, but you can get very close to that by using package objects:
src/main/scala/yourpackage/package.scala:
package object yourpackage {
def function(x: Int) = x*x
}
src/main/scala/yourpackage/Other.scala:
package yourpackage
object Other {
def main(args: Array[String]) {
println(function(10)); // Prints 100
}
}
Note how function is used in Other object - without any qualifiers. Here function belongs to a package, not to some specific object/class.
As the other answers have indicated, its not possible to define a function without an object or class, because in Scala, functions are objects and (for example) Function1 is a class.
However, it is possible to define a function without an enclosing class or object. You do this by making the function itself the object.
src/main/scala/foo/bar/square.scala:
package foo.bar
object square extends (Int => Int) {
def apply(x: Int): Int = x * x
}
extends (Int => Int) is here just syntactic sugar for extends Function1[Int, Int].
This can then be imported and used like so:
src/main/scala/somepackage/App.scala:
package foo.bar.somepackage
import foo.bar.square
object App {
def main(args: Array[String]): Unit = {
println(square(2)) // prints "4"
}
}
No, functions as "first-class objects" means they are still objects.
However, it is still easy to construct a Scala application that does nothing but invoke a function that is arbitrarily composed.
One Odersky meme is that Scala's fusion of FP and OOP exploits modularity of OOP. It's a truism that Scala doesn't strive for "pure FP"; but OOP has real consequences for everyday programming, such as that a Map is a Function, as is a Set or a String (by virtue of enrichment to StringOps).
So, although it's possible to write a program that just invokes a function and is not structured OOPly, the language does not support active avoidance of OOP in the sense of exposure to inheritance and other unFP things like mutable state and side effects.

Generating a Scala class automatically from a trait

I want to create a method that generates an implementation of a trait. For example:
trait Foo {
def a
def b(i:Int):String
}
object Processor {
def exec(instance: AnyRef, method: String, params: AnyRef*) = {
//whatever
}
}
class Bar {
def wrap[T] = {
// Here create a new instance of the implementing class, i.e. if T is Foo,
// generate a new FooImpl(this)
}
}
I would like to dynamically generate the FooImpl class like so:
class FooImpl(val wrapped:AnyRef) extends Foo {
def a = Processor.exec(wrapped, "a")
def b(i:Int) = Processor.exec(wrapped, "b", i)
}
Manually implementing each of the traits is not something we would like (lots of boilerplate) so I'd like to be able to generate the Impl classes at compile time. I was thinking of annotating the classes and perhaps writing a compiler plugin, but perhaps there's an easier way? Any pointers will be appreciated.
java.lang.reflect.Proxy could do something quite close to what you want :
import java.lang.reflect.{InvocationHandler, Method, Proxy}
class Bar {
def wrap[T : ClassManifest] : T = {
val theClass = classManifest[T].erasure.asInstanceOf[Class[T]]
theClass.cast(
Proxy.newProxyInstance(
theClass.getClassLoader(),
Array(theClass),
new InvocationHandler {
def invoke(target: AnyRef, method: Method, params: Array[AnyRef])
= Processor.exec(this, method.getName, params: _*)
}))
}
}
With that, you have no need to generate FooImpl.
A limitation is that it will work only for trait where no methods are implemented. More precisely, if a method is implemented in the trait, calling it will still route to the processor, and ignore the implementation.
You can write a macro (macros are officially a part of Scala since 2.10.0-M3), something along the lines of Mixing in a trait dynamically. Unfortunately now I don't have time to compose an example for you, but feel free to ask questions on our mailing list at http://groups.google.com/group/scala-internals.
You can see three different ways to do this in ScalaMock.
ScalaMock 2 (the current release version, which supports Scala 2.8.x and 2.9.x) uses java.lang.reflect.Proxy to support dynamically typed mocks and a compiler plugin to generate statically typed mocks.
ScalaMock 3 (currently available as a preview release for Scala 2.10.x) uses macros to support statically typed mocks.
Assuming that you can use Scala 2.10.x, I would strongly recommend the macro-based approach over a compiler plugin. You can certainly make the compiler plugin work (as ScalaMock demonstrates) but it's not easy and macros are a dramatically superior approach.