Composition in Scala, based on objects (singletons) - scala

I want to make a composition with two objects. I can do it with objects nesting:
object Composition {
object SomePartOfComposition {
// some body
}
}
But the body of SomePartOfComposition is such long, that I want it in a separate file. How can I do that?
// edit
I know, that I can use trait. But I want strict one to one relation - it is a singleton.

object Composition {
object SomePartOfComposition extends SomePartTrait
}
trait SomePartTrait{
//in it's own file
//implement the body here
}

You haven't specified why it matters that one object is nested in the other, so I assume that you just want the syntax to look like A.B. So:
//File A
object A {
val B = C
}
// File C
object C {
import A._
// All your code, written just like it was placed inside A
}
If this is not what you want, please edit the question to explain all the criteria.

You can have a strict one to one relationship when using traits by defining the self type of the trait to be the type of the object:
object Composition {
object SomePartOfComposition extends SomePartOfCompositionTrait
}
trait SomePartOfCompositionTrait {
this: Composition.SomePartOfComposition.type =>
// body
}

Related

Create sublass instance from ancestor

i am quite new in Scala. Have class named 'Document' and a few classes, like 'Doc1' and 'Doc2' which are children of Document. So:
abstract class Document(id: Int, xmlString: String) {
// make some operations and create an instance of subtype
}
case class Doc1 extends Document {
// some subclass specific methods
}
case class Doc2 extends Document {
// some subclass specific methods
}
Would like to run Document constructor and as a result, create an instance of Doc1 or Doc2 conditionally due to passed paramethers. Shall i add some auxiliary constructors in 'Document' class?
Any idea welcome.
The best practice is to use companion object/singleton object:
abstract class Document { ... }
object Document {
def apply(docType: String) = {
if (docType == "doc1") {
Doc1()
} else {
Doc2()
}
}
}
and the usage of it:
val document1 = Document("doc1")
Of course, it's just a simple example - you can change the docType to sealed class and check the type by pattern matching.
Update - by #crater2150 comment - you can use the apply instead of different function name, so you will write Document("doc1") instead of Document.someFunctionName("doc1")

Playframework, where to put Json Writes and Reads for reuse?

I have two controllers who writes and reads the same AccountModel case class. This class is an adapter for my "domain" object Account who flatten some collections and transform objects references (Map[Role, Auth]) to a explicit key reference (Set[AuthModel(rolekey:String, level:Int)]).
I would like to reuse this AccountModel and his implicits Writes and Reads but don't know how the achieve that 'the scala way'.
I would say in an object Models with my case classes as inner classes and all the related implicits but I think that this would become unreadable soon.
What are you used to do, where do you put your reusable Json classes, do you have some advices ?
Thanks a lot
There are two main approaches.
Approach 1: Put them on a companion object of your serializable object:
// in file AccountModel.scala
class AccountModel(...) {
...
}
object AccountModel {
implicit val format: Format[AccountModel] = {...}
}
This way everywhere you import AccountModel, the formatters will be also available, so everything will work seamlessly.
Approach 2: Prepare a trait with JSON formatters:
// in a separate file AccountModelJSONSupport.scala
import my.cool.package.AccountModel
trait AccountModelJsonSupport {
implicit val format: Format[AccountModel] = {...}
}
With this approach whenever you need serialization, you have to mix the trait in, like this:
object FirstController extends Controller with AccountModelJsonSupport {
// Format[AccountModel] is available now:
def create = Action(parse.json[AccountModel]) { ... }
}
EDIT: I forgot to add a comparison of the two approaches. I usually stick to approach 1, as it is more straightforward. The JSONSupport mixin strategy is however required when you need two different formatters for the same class or when the model class is not your own and you can't modify it. Thanks for pointing it out in the comments.

Object extends Trait, Class extends Trait, both have to implement method

I have the following setup:
trait A
{
def doSomething(): Unit;
}
object B extends A
{
override def doSomething(): Unit =
{
// Implementation
}
}
class B(creator: String) extends A
{
override def doSomething(): Unit =
{
B.doSomething() // Now this is just completely unnecessary, but the compiler of course insists upon implementing the method
}
}
Now you may wonder why I even do this, why I let the class extend the trait as well.
The problem is, that somewhere in the Program there is a Collection of A.
So somewhere:
private val aList: ListBuffer[A] = new ListBuffer[A]
and in there, I also have to put Bs (among other derivates, namely C and D)
So I can't just let the B-class not extend it.
As the implementation is the same for all instances, I want to use an Object.
But there is also a reason I really need this Object. Because there is a class:
abstract class Worker
{
def getAType(): A
def do(): Unit =
{
getAType().doSomething()
}
}
class WorkerA
{
def getAType(): A =
{
return B
}
}
Here the singleton/object of B gets returned. This is needed for the implementation of do() in the Worker.
To summarize:
The object B is needed because of the generic implementation in do() (Worker-Class) and also because doSomething() never changes.
The class B is needed because in the collection of the BaseType A there are different instances of B with different authors.
As both the object and the class have to implement the trait for above reasons I'm in kind of a dilemma here. I couldn't find a satisfying solution that looks neater.
So, my question is (It turns out as a non-native-speaker I should've clarified this more)
Is there any way to let a class extend a trait (or class) and say that any abstract-method implementation should be looked up in the object instead of the class, so that I must only implement "doSomething()" (from the trait) once (in the object)? As I said, the trait fulfills two different tasks here.
One being a BaseType so that the collection can get instances of the class. The other being a contract to ensure the doSomething()-method is there in every object.
So the Object B needs to extend the trait, because a trait is like a Java interface and every (!) Object B (or C, or D) needs to have that method. (So the only option I see -> define an interface/trait and make sure the method is there)
edit: In case anyone wonders. How I really solved the problem: I implemented two traits.
Now for one class (where I need it) I extend both and for the other I only extend one. So I actually never have to implement any method that is not absolutely necessary :)
As I wrote in the comment section, it's really unclear to me what you're asking.
However, looking at your code examples, it seems to me that trait A isn't really required.
You can use the types that already come with the Scala SDK:
object B extends (()=>Unit) {
def apply() { /* implementation */ }
}
Or, as a variant:
object B {
val aType:()=>Unit = {() => /* implementation */ }
}
In the first case, you can access the singleton instance with B, in the second case with B.aType.
In the second case, no explicit declaration of the apply method is needed.
Pick what you like.
The essential message is: You don't need a trait if you just define one simple method.
That's what Scala functions are for.
The list type might look like this:
private val aList:ListBuffer[()=>Unit] = ???
(By the way: Why not declare it as Seq[()=>Unit]? Is it important to the caller that it is a ListBuffer and not some other kind of sequence?)
Your worker might then look like this:
abstract class Worker {
def aType:()=>Unit // no need for the `get` prefix here, or the empty parameter list
def do() {aType()}
}
Note that now the Worker type has become a class that offers a method that invokes a function.
So, there is really no need to have a Worker class.
You can just take the function (aType) directly and invoke it, just so.
If you always want to call the implementation in object B, well - just do that then.
There is no need to wrap the call in instances of other types.
Your example class B just forwards the call to the B object, which is really unnecessary.
There is no need to even create an instance of B.
It does have the private member variable creator, but since it's never used, it will never be accessed in any way.
So, I would recommend to completely remove the class B.
All you need is the type ()=>Unit, which is exactly what you need: A function that takes no parameters and returns nothing.
If you get tired of writing ()=>Unit all the time, you can define a type alias, for example inside the package object.
Here is my recommentation:
type SideEffect = ()=>Unit
Then you can use SideEffect as an alias for ()=>Unit.
That's all I can make of it.
It looks to me that this is probably not what you were looking for.
But maybe this will help you a little bit along the way.
If you want to have a more concrete answer, it would be nice if you would clarify the question.
object B doesn't really have much to do with class B aside from some special rules.
If you wish to reuse that doSomething method you should just reuse the implementation from the object:
class B {
def doSomething() = B.doSomething()
}
If you want to specify object B as a specific instance of class B then you should do the following:
object B extends B("some particular creator") {
...
}
You also do not need override modifiers although they can be handy for compiler checks.
The notion of a companion object extending a trait is useful for defining behavior associated with the class itself (e.g. static methods) as opposed to instances of the class. In other words, it allows your static methods to implement interfaces. Here's an example:
import java.nio.ByteBuffer
// a trait to be implemented by the companion object of a class
// to convey the fixed size of any instance of that class
trait Sized { def size: Int }
// create a buffer based on the size information provided by the
// companion object
def createBuffer(sized: Sized): ByteBuffer = ByteBuffer.allocate(sized.size)
class MyClass(x: Long) {
def writeTo(buffer: ByteBuffer) { buffer.putLong(x) }
}
object MyClass extends Sized {
def size = java.lang.Long.SIZE / java.lang.Byte.SIZE
}
// create a buffer with correct sizing for MyClass whose companion
// object implements Sized. Note that we don't need an instance
// of MyClass to obtain sizing information.
val buf = createBuffer(MyClass)
// write an instance of MyClass to the buffer.
val c = new MyClass(42)
c.writeTo(buf)

Calling a member method without the 'this' keyword

In Scala, is it possible to call a member method without having to call an instance of itself?
For instance, having this class:
class Model {
def action(value : String) = {
// Do action
}
}
this object implementation works:
object MyModel extends Model {
this action "doSomething"
}
But I would like to do something like this:
object MyModel extends Model {
action "doSomething"
}
As one does with Java property files, since it's a neat way to define the state of an object.
I managed to define an alias for this:
def declare = this
but it's the same issue of having to use a word in front of the call to the member method.
Is there an option to do this?
Yes, but you have to use parentheses:
object MyModel extends Model {
action("doSomething")
}
See this answer for example for more detail about when parentheses can or cannot be omitted.
As a side note, you could also alias this as follows:
object MyModel extends Model { declare =>
declare action "doSomething"
}
This is often useful if you want to refer to a class's this from inside of a nested class—it's a bit less verbose than writing Outer.this.x as you would in Java.

when to use singleton objects and when to use actual objects in scala

I would like to know if there is any specific rule or if there is a rule of thumb to be followed on using actual objects in scala vs singleton objects in scala
say i have a class like this
class GetDataInput {
def getNameInput() {
println("Enter the name value: ")
}
def getTypeInput() {
println("Enter the type value: ")
}
def getBothInput() {
println("Enter the name value: ")
println("Enter the type value: ")
}
}
is it better to use it in regular terms like
val someval = new GetDataInput()
someval.getNameInput()
or is it good to create a singleton object for this class and access the methods using that
object GetDataInput {
def getNameInp() = getNameInput()
}
Any pointers on this?
Generally you make an object when:
It makes absolutely no sense of having different instances of a potential class, for example, to enclose several pure functions (like methematical functions, factory methods)
You want to write the equivalent of java static method or static final constants. (see Companion objects).
You want a simpler alternative for enum values (a sealed trait extended by objectinstances).
In your example, all the functions are pure, and the class is stateless. Therefore all instances will be strictly equal. It makes sense to turn it into an object:
object GetDataInput {
def getNameInput() {
println("Enter the name value: ")
}
...
}
If you made the wrong choice, don't worry, it is easy to refactor. Usually you can keep all existing calls to the object, simply by extracting the methods in a trait:
trait GetDataInput {
def getNameInput() {
println("Enter the name value: ")
}
}
object GetDataInput extends GetDataInput //Bring all traits methods into the object
// to keep previous behaviour
class MyGetDataInput( whatever: Foo ) extends GetDataInput {
...
}
The question is rather: "Do you need different instances of a type?" If so, then go for a class (or a trait), if not go for a singleton. And btw there are no specific guidelines for the language you are using only because it has the singleton pattern built into it.
In scala, one primary use of objects is to fill the role of singletons. If you want to use a class as a singleton, just declare the class itself as an object. Then you could do:
GetDataInput.getNameInput()
Internally, scala will lazily create a single instance of your class and keep it alive for the duration of the program, so anytime you call a method on the object, you're really calling methods of a singleton instance of the class managed by the scala runtime.