Why do people define object extends its companion class? - scala

I find this kind of code is very common in Lift framework, written like this:
object BindHelpers extends BindHelpers {}
What does this mean?

In this case, BindHelpers is a trait and not a class. Let foo() to be a method defined in BindHelpers, to access it you can either.
Use it through the companion object: BindHelpers.foo()
Mix the trait BindHelpers in a class and thus be able to access the methods inside of it.
For instance:
class MyClass extends MyParentClass with BindHelpers {
val a = foo()
}
The same techniques is used in Scalatest for ShouldMatchers for instance.

You can find David Pollak's answer to the same question in the liftweb group.

It's interesting for an object to extend its companion class because it will have the same type as the class.
If object BindHelpers didn't extend BindHelpers, it would be of type BindHelpers$.

It might be that the pattern here is other. I don't know Lift to answer this, but there's a problem with object in that they are not mockable. So, if you define everything in a class, which can be mocked, and then just makes the object extend it, you can mock the class and use it instead of the object inside your tests.

Related

What are the advantages or disadvantages of declaring function/method in companion objects versus declaring them in traits?

I am new to Scala and I now started a project in Scala and I see similar to the following construct:
trait SomeTrait extends SomeOtherStuff with SomeOtherStuff2
object SomeTrait {
def someFunction():Unit = { ??? }
}
I understand that for a class, companion objects hold methods that are used in a "static", like Factory methods in Java or something alike, but what about traits, why not put these methods in traits?
The first style is called mixin, it used to be somewhat popular back in the days.
It could be replaced by the following code:
object SomeOtherStuff {
def someMethod(): String
}
object SomeObj {
import SomeOtherStuff._
//now someMethod is available
def otherMethod(): String = someMethod + "!"
}
object Caller {
import SomeObj._
import SomeOtherStuff._
//utility methods from both objects are available here
}
Pros of mixins:
If SomeTrait extends 10 other mixins then extending this trait would allow to scrap 10 import statements
Cons of mixins:
1) creates unnecessary coupling between traits
2) awkward to use if the caller doesn't extend the mixin itself
Avoiding mixins for business-logic code is a safe choice.
Although I'm aware of 2 legitimate usecases:
1) importing DSLs
e.g. ScalaTest code :
class SomeSuite extends FunSuite with BeforeAndAfter {...}
2) working (as a library author) with implicit parameters:
e.g. object Clock extends LowPriorityImplicits
(https://github.com/typelevel/cats-effect/blob/master/core/shared/src/main/scala/cats/effect/Clock.scala#L127)
Another perspective to this is the OOP principle Composition Over Inheritance.
Pros of companion objects (composition):
composition can be done at runtime while traits are defined at compile time
you can easily have multiple of them. You don't have to deal with the quirks of multiple inheritance: say you have two traits that both have a method with the name foo - which one is going to be used or does it work at all? For me, it's easier to see the delegation of a method call, multiple inheritance tends to become complex very fast because you lose track where a method was actually defined
Pros of traits (mixins):
mixins seem more idiomatic to reuse, a class using a companion object of another class is odd. You can create standalone objects though.
it's cool for frameworks because it adds the frameworks functionality to your class without much effort. Something like that just isn't possible with companion objects.
In doubt, I prefer companion objects, but it always depends on your environment.

References to case objects with trait usage

I've encountered something which I don't quite understand, so lets begin:
If i've got this object:
case object StartMessage
written like above and then obtain its references from two different classes:
class Test2 {
def print(){
println(Integer.toHexString(System.identityHashCode(StartMessage)))
}
}
class Test1 {
def print(){
println(Integer.toHexString(System.identityHashCode(StartMessage)))
}
}
as expected result is:
object ActorMain extends App{
new Test1().print()//45c8e616
new Test2().print()//45c8e616
}
But when i change case object to pack it in trait:
trait model{
case object StartMessage
}
then my classes will have declaration like:
class Test1 extends model{
class Test2 extends model{
I receive:
45c8e616
7d417077
*1. Could you explain it to me? I was thinking that objects are one in whole application, so when i create Trait with objects in it, every time i will extends (use "with") those trait, the object will be the same, not somewhat trait scoped.
*2. Is there another way to obtain functionality to "add" same objects only with extending trait to concrete classes, and not make them visible for whole application? Case is to have cleaner code with possibility to "mark" classes as "they use those objects, while others don't"
Objects defined within trait are singletons given trait scope. It is actually referring to the instance of a trait, not the trait itself. And the resulting behavior is the one that you see -> objects are created per instance. And this leads to the conclusion that you cannot define objects by extending traits to be shared across different classes. There was similar question on SO some time ago, I'll try to find it later.
Personally I would go for passing to classes some sort of a context to provide shared resources.

Avoid duplicate type alias in Scala class and companion object

I'm a newbie in Scala, and I have a Scala program with a class and a companion object, and I want to use a type alias that is used :
To define the methods of the class.
Also I want to use the alias outside the class. For that I find useful to define the alias in the companion object, to import the alias from the companion object. I also have some implicits defined in the companion object so this is just natural.
The concrete code is available at https://github.com/juanrh/Surus/blob/1cfd55ed49c4d1b22e53babe07bcf44fd74e3072/src/main/scala/org/surus/spark/SurusRDDFunctions.scala, the type alias is PMMLPrediction and the class is SurusRDDFunctions. Currently the code works but I have defined the alias both in the class and the companion, which is not very nice. If I remove the definition of the alias in the class then the class is not able to find it, which seems weird. So I think I'm probably doing something wrong, any ideas?
Thanks a lot in advance for your help!
Greetings,
Juan
Given the companion object
object Example {
type MyString = String
}
You can access the type directly through to the companion object
class Example (val name: Example.MyString) { }
Or by importing it from the companion object
class Example {
import Example._
val name: MyString = "example"
}

Scala generic: require method to use class's type

I'm pretty new to Scala. I'm trying to write an abstract class whose methods will be required to be implemented on a subclass. I want to use generics to enforce that the method takes a parameter of the current class.
abstract class MySuper{
def doSomething:(MyInput[thisclass]=>MyResult)
}
class MySub extends MySuper{
override def doSomething:(MyInput[MySub]=>MyResult)
}
I know that thisclass above is invalid, but I think it kind of expresses what I want to say. Basically I want to reference the implementing class. What would be the valid way to go about this?
You can do this with a neat little trick:
trait MySuper[A <: MySuper[A]]{
def doSomething(that: A)
}
class Limited extends MySuper[Limited]{
def doSomething(that: Limited)
}
There are other approaches but I find this one works fairly well at expressing what you'd like.

How can I use MockitoSugar to mock an object (singleton) method?

Is there a way in scala to use MockitoSugar in order to mock a method of an object that is a scala singleton?
Your best bet to deal with singletons for mocking is to first do a little rework on the structure of the singleton itself. Use a trait to define the operations and then have the object extend the trait like so:
trait Fooable{
def doFoo:String = "foo"
}
object Foo extends Fooable
Then, in any class that needs the Foo object, declare it as an input or something that can be set (DI), but decalare it as the trait instead like this:
class MyFooUser(foo:Fooable = Foo){
}
That way by default it uses the object, but when constructing for your tests, you can give it a mocked Fooable instead. There are a bunch of ways to handle getting the Fooable into your classes (this is one) and that's not really in scope for this answer. The answer really is about using a trait first to define the methods and then having the object extend that trait and then referring to it as the trait in any class that needs it. That will allow you to mock it effectively.
Mockito won't help with objects, but you can try to use ScalaMock instead.