What is the meaning of "new {}" in Scala? - scala

I am studying about .sbt extension file reference docs. What codes I am confused is:
lazy val version = new {
val finatra = "2.1.2"
}
I know val finatra can be accessed by version.finatra, but it seems like "object singleton." Such like this:
object version {
val finatra = "2.1.2"
}
In this case, I can also access val finatra by version.finatra.
I know the later one is the way to create "object singleton".
How about the former one? Thanks

In short, it is creating new instance of Anonymous Type
According to the Scala Language Spec:
Consider the following structural instance creation expression:
new { def getName() = "aaron" }
This is a shorthand for the general instance creation expression
new AnyRef{ def getName() = "aaron" }
The latter is in turn a shorthand for the block
{ class anon$X extends AnyRef{ def getName() = "aaron" }; new anon$X }

Related

JavaScript object as function parameter

I'm writting a function transpiled with Scala.js that should accept any random JavaScript object.
Ex:
// This has been transpiled using Scala.js
var my_service = new com.myself.Service();
// This is plain JavaScript
var result1 = service({ hello: "yolo" });
var result2 = service({ whatever: "ok", really: { yes: "right", no: "don't" } });
However, I can't find the input type that matches it.
What would be the Scala-function signature to get such a thing?
Could it be used then as a "Scala/JS case class" easily?
Note (if it helps giving a direction for the answers): these objects have, in the real life, an expected schema but it cannot be created as JS object generated from Scala.js since it comes from another consumed service.
Since the objects have an expected schema, its probably easiest to define a facade type:
#js.native
trait Args extends js.Object {
val hello: js.UndefOr[String]
val whatever: js.UndefOr[String]
val really: js.UndefOr[ReallyArgs]
}
#js.native
trait Really extends js.Object {
val yes: String
val no: String
}
def myMethod(args: Args): Unit = {
println(args.hello)
println(args.really.map(_.yes))
}

Implements trait with an anonymous object in Scala

I have a trait definition:
trait T {
def name: String
}
I can create an object like:
val o = new {
val name: String = "anonymous"
} with T
But I cannot create the object in the following way:
val o = new {
def name: String = "anonymous"
} with T
The compiler said ';' or newline expected in line } with T. The only different is I used def instead of val in the second implementation.
I know that method can be defined in an anonymous object, but why I cannot use in this way here?
The curly brackets in your two examples are "early definitions", explained here:
In Scala, what is an "early initializer"?
So it's initialization code, and not something that gets mixed in to your object.
The idea was raised on the Scala JIRA, and closed as "not a bug", here:
https://issues.scala-lang.org/browse/SI-912

What is this Scala 'new' syntax

From the ScalaTest docs:
class ExampleSpec extends FlatSpec {
def fixture =
new {
val builder = new StringBuilder("ScalaTest is ")
val buffer = new ListBuffer[String]
}
...
I don't understand how the new keyword is being used here. fixture is obviously a function, which declares and returns... what? It seems to be an object, since it has members (builder & buffer) that can be accessed with . notation.
Is what is being created here an anonymous class that is a subclass of AnyRef?
Yep, it returns instance of anynomous class. It is not hard to check it by yourself in REPL session:
scala> def fixture = new { val string = "mr. String" }
fixture: Object{val string: String}
Java can do the essentially same thing, believe it or not. The following is valid Java
(new Object() {
public void sayHello() {
System.out.println("hello!");
}
}).sayHello();
The Java version is just a mildly more verbose syntax and has a type system limitation that makes it mostly useless.
More about it here http://james-iry.blogspot.com/2009/04/java-has-type-inference-and-refinement.html

Mockito for Objects in Scala

I'm using Scala 2.10, specs2 and Mockito. I want to mock scala.io.Source.fromURL(). The issue seems to be fromURL() is a function in io.Source's object.
val m = mock[io.Source]
m.fromURL returns io.Source.fromString("Some random string.")
It's a pretty straightforward mock in an Unit test. Why isn't it working?
Thanks!
Instead of mocking it, you could try spying it as follows:
val m = spy(io.Source)
Or you could mock it as follows:
val m = mock[io.Source.type]
But then how are you using Source in the class you are testing? If you had an example class like so:
class MyClass{
def foo = {
io.Source.doSomething //I know doSomething is not on Source, call not important
}
}
Then in order to take advantage of mocking/spying, you'd have to structure your class like so:
class MyClass{
val source = io.Source
def foo = {
source.doSomething
}
}
And then your test would have to look something like this:
val mockSource = mock[io.Source.type]
val toTest = new MyClass{
override val source = mockSource
}
In the Java world, static methods are the bane of mocking. In the Scala world, calls to objects can also be troublesome to deal with for unit tests. But if you follow the code above, you should be able to properly mock out an object based dependency in your class.
Good news! With the latest 1.16 release of mockito-scala, you can now mock scala objects.
To enable withObjectMocked feature, it is mandatory to create the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line:
mock-maker-inline
Example:
object FooObject {
def simpleMethod: String = "not mocked!"
}
"mock" should {
"stub an object method" in {
FooObject.simpleMethod shouldBe "not mocked!"
withObjectMocked[FooObject.type] {
FooObject.simpleMethod returns "mocked!"
//or
when(FooObject.simpleMethod) thenReturn "mocked!"
FooObject.simpleMethod shouldBe "mocked!"
}
FooObject.simpleMethod shouldBe "not mocked!"
}
}
See: https://github.com/mockito/mockito-scala#mocking-scala-object
Years later, above answer doesn't work as others have pointed out.
And you cannot mock the scala.io.Source object.
Can I mock final / private methods or classes? This is not supported, as mocks generated with macros are implemented as subclasses of the type to mock. So private and final methods cannot be overridden. You may want to try using an adapter or façade in your code to make it testable. It is better to test against a trait/interface instead of a concrete implementation. There are libraries that support this kind of mocking, such as PowerMock. Be aware that this kind of mocking involves Bytecode manipulation, which has the risk that your test double diverges from the actual implementation.
So what I did is an work around to abstract out scala.io.Source.fromUrl() as a function argument and pass in mocked function in tests.
// original func
def aFuncThatUsesSource() = {
val source = scala.io.Source("127.0.0.1:8080/...")
val result = source.mkString
Try(source.close())
result
}
// test friendly func that accepts `scala.io.Source.fromURL` as arg
def aTestFriendlyFunc(makeApiCall: String => BufferedSource) = {
val source = makeApiCall("127.0.0.1:8080/...")
val result = source.mkString
Try(source.close())
result
}
....
// test spec
def testyMcTesterson = () => {
val makeApiCall = mockFunction[String, BufferedSource]
makeApiCall.expects("something...")
.returns( new BufferedSource(new ByteArrayInputStream("returns something".getBytes)) )
aTestFriendlyFunc(makeApiCall) shouldEqual "returns something"
}

Scala trait mixins for an object/ typesafe Config

This is an OO design Q. Im using typesafe Config in my App. The Config interface is very useful, however there are a couple of fields in my applications; config file that are mandatory. What I wanted to do was create a subInterface of Config and add these 2 top-level methods . Something like this
trait AppConfig extends Config{
def param1:String
def param2:String
}
However creating a real instance of AppConfig given an instance of Config doesnt seem feasible.( I dont want to create wrapper object and duplicate all the methods on the Config interface) . Ideally , Im looking for something that would achieve something close to this
val conf:Config = //get config object from somewhere
return conf with AppConfig { overrider def param1 = {"blah"} }
I do understand the last line is not valid . But Im looking for a pattern/construct with an equivalent functionality.
We've been using Configrity for things like this. Here's an example:
We keep our compiled defaults that we use for unit test/etc in objects
object DefaultConfigs {
val defaultConfig = Configuration(
"param1" -> "blah"
)
val otherConfig = Configuration(
"param2" -> "blah"
)
val appConfig = defaultConfig.include(otherConfig)
}
And then at run time we can include them or not
val appConfig = Configuration.load(pathToConfig) include DefaultConfigs.appConfig
What you are looking for is basically what some call a "dynamic mixin". This is not supported out of the box by scala.
Someone developed a compiler plugin to support this: http://www.artima.com/weblogs/viewpost.jsp?thread=275588
However it's a bit old and the project does not seem active anymore.
A better alternative would be to implement this feature using scala macros (requires scala 2.10, which has no stable release yet).
All of this is probably overkill in your case though. Until some well tested library is available, I would advise to just create the proxy by hand (however dull that may look):
trait ConfigProxy extends Config {
def impl: Config
// Forward to the inner config
def root: ConfigObject = impl.root
def origin: ConfigOrigin = impl.origin
//... and so on
}
val conf:Config = //get config object from somewhere
val myConf: AppConfig = new AppConfig with ConfigProxy {
val impl = conf
val param1:String = "foo"
val param2:String = "bar"
}
How about using a combination of Dynamic and Reflection. Dynamic to handle your convenience methods and reflection to handle the methods on config.
Here's a stab:
class ConfigDynamic(val config: Config) extends Dynamic {
def selectDynamic(name: String)= {
name match {
case "field1" =>
config.getString("field1")
case x # _ =>
// overly simplified here
val meth = configClass.getDeclaredMethod(x)
meth.invoke(config)
}
}
}