I have a companion object which looks as follows:
case class ShowItemMessageStreamMock[A](item: A)
object ShowItemMessageStreamMock extends ShowItemMessageStream
{
def addItemToMessageStream[A](view: A): Unit =
{
new ShowItemMessageStreamMock(view)
}
}
and I have a assertion, which looks like this:
assert(ShowItemMessageStreamMock.item.nonEmpty)
( just pretend, that the addItemToMessageStream method ran and item has a value in it )
but when I hover over the item in the assertion, I get this error message:
value item is not a member of object
ShowItemMessageStreamMock
I thought, I can access all values of each companion?
So my question is, why can´t I acces this item value?
So my question is, why can´t I acces this item value?
Because it doesn't exist. The companion object ShowItemMessageStreamMock does not have an item member.
You could put the assertion inside the case class like this:
case class ShowItemMessageStreamMock[A](item: A) {
assert(item.nonEmpty)
}
Of course this won't work because item is of unknown type and may not have a nonEmpty method, but at least you are checking the right value! And there are better ways of enforcing this than using an assertion.
But the following code is also messed up because it creates an object and then discards all references to it:
def addItemToMessageStream[A](view: A): Unit =
{
new ShowItemMessageStreamMock(view)
}
It's probably worth taking a step back and explaining what it is you are actually trying to do.
Related
I am reading this example from their docs:
class Email(val username: String, val domainName: String)
object Email {
def fromString(emailString: String): Option[Email] = {
emailString.split('#') match {
case Array(a, b) => Some(new Email(a, b))
case _ => None
}
}
}
println(Email.fromString("scala.center#epfl.ch"))
val scalaCenterEmail = Email.fromString("scala.center#epfl.ch")
scalaCenterEmail match {
case Some(email) => println(
s"""Registered an email
|Username: ${email.username}
|Domain name: ${email.domainName}
""")
case None => println("Error: could not parse email")
}
My questions:
What is Some and Option?
What is a factory method (just some function that creates a new object and returns it?)
What is the point of companion objects? Is it just to contain functions that are available to all instances of class? Are they like class methods in Ruby?
What is Some and Option?
Option is a data structure that represents optionality, as the name suggests. Whenever a computation may not return a value, you can return an Option. Option has two cases (represented as two subclasses): Some or None.
In the example above, the method Email.fromString can fail and not return a value. This is represented with Option. In order to know whether the computation yielded a value or not, you can use match and check whether it was a Some or a None:
Email.fromString("scala.center#epfl.ch") match {
case Some(email) => // do something if it's a Some
case None => // do something it it's a None
}
This is much better than returning null because now whoever calls the method can't possibly forget to check the return value.
For example compare this:
def willReturnNull(s: String): String = null
willReturnNull("foo").length() // NullPointerException!
with this
def willReturnNone(s: String): Option[String] = None
willReturnNone("foo").length() // doesn't compile, because 'length' is not a member of `Option`
Also, note that using match is just a way of working with Option. Further discussion would involve using map, flatMap, getOrElse or similar methods defined on Option, but I feel it would be off-topic here.
What is a factory method (just some function that creates a new object and returns it?)
This is nothing specific to Scala. A "factory method" is usually a static method that constructs the value of some type, possibly hiding the details of the type itself. In this case fromString is a factory method because it allows you create an Email without calling the Email constructor with new Email(...)
What is the point of companion objects? Is it just to contain functions that are available to all instances of class? Are they like class methods in Ruby?
As a first approximation, yes. Scala doesn't have static members of a class. Instead, you can have an object associated with that class where you define everything that is static.
E.g. in Java you would have:
public class Email {
public String username;
public String domain;
public static Optional<Email> fromString(String: s) {
// ...
}
}
Where as in Scala you would define the same class as roughly:
class Email(val username: String, val domain: String)
object Email {
def fromString(s: String): Option[Email] = {
// ...
}
}
I would like to add some examples/information to the third question.
If you use akka in companion object you can put every message that you use in case method (it should proceed and use by actor). Moreover, you can add some val for a name of actors or other constant values.
If you work with JSON you should create a format for it (sometimes custom reads and writes). This format you should put inside companion object. Methods to create instances too.
If you go deeper to Scala you can find case classes. So a possibility to create an object of this class without new is because there is a method apply in "default" companion object.
But in general, it's a place where you can put every "static" method etc.
About Option, it provides you a possibility to avoid some exception and make something when you don't have any values.
Gabriele put an example with email, so I'll add another one.
You have a method that sends email, but you take email from User class. The user can have this field empty, so if we have something like it
val maybeEmail: Option[String] = user.email you can use for example map to send an email
maybeEmail.map(email => sendEmail(email))
So if you use it, during writing methods like above you don't need to think that user specify his email or not :)
I'm currently writing a parser in Scala and am trying to create an eat function that checks whether the next Token is of a certain case class and if so, consumes it. My current try is as follows and works correctly:
def eat[T](tokenType: TypeTag[T]) = currentToken match {
case Plus() => if (tokenType == typeTag[Plus]) currentToken = lexer.getNextToken() else throw new Exception(tokenType.toString ++ " expected, " ++ currentToken.toString)
case Minus() => if (tokenType == typeTag[Minus]) currentToken = lexer.getNextToken() else throw new Exception(tokenType.toString ++ " expected, " ++ currentToken.toString)
}
Tokens are defined as follows:
trait Token
case class Plus() extends Token
case class Minus() extends Token
case class IntConst(n: Int) extends Token
case class FloatConst(x: Float) extends Token
Previously I did it with strings to specify the types, but passing a TypeTag already removes the possibility to try to eat a non existing type.
However, tldr, what I am trying to achieve is to be able to pass a type or class as argument and to check whether the currentToken is of that class.
I did find out how to pass a class as an argument with def something(c: class[_]), but then I would only know how to compare this to a given type, say Int. However, I want to compare it to the type of my currentToken. Can anybody point me in the right direction for achieving that?
Thanks.
What I am hoping to achieve, (extended version)
At the current moment, I have working code, that does what is expected in (I think) a relatively efficient way. However, for every Token case class added, a new line to this function would have to be added as well, even though the main question answered by the eat function does not change. In an ideal world, I would hope to write something like the following pseudocode:
def eat(tokenClass: Class) = {
if (classOf(currentToken) == tokenClass) getNextToken else throw exception
}
Which would never have to get extended. (Even better by the way would be if the parameter would only be allowed to be a case class of the trait Token).
Since what you want to compare is actually runtime classes (and not compile time types), you can do something like this:
def eat[T](implicit T: ClassTag[T]) =
if (T.runtimeClass == currentToken.getClass) getNextToken else throw exception
However, this will cause problems if your classes have type parameters (because of type erasure).
I have a tree object that implements lazy depth-first-search as a TraversableView.
import collection.TraversableView
case class Node[T](label: T, ns: Node[T]*)
case class Tree[T](root: Node[T]) extends TraversableView[T, Traversable[_]] {
protected def underlying = null
def foreach[U](f: (T) => U) {
def dfs(r: Node[T]): TraversableView[T, Traversable[_]] = {
Traversable(r.label).view ++ r.ns.flatMap(dfs(_))
}
dfs(root).foreach(f)
}
}
This is appealingly concise and appears to work; however, the underlying = null method makes me nervous because I don't understand what it means. (IntelliJ wrote that line for me.) I suppose it might be correct, because in this case there is no underlying strict representation of the tree, but I'm not sure.
Is the above code correct, or do I have to do something more with underlying?
Users of views will expect to be able to call force to get a strict collection. With your implementation, calling force on a tree (or any transformation of a tree—e.g., tree.take(10).filter(pred), etc.) will result in a null pointer exception.
This may be fine with you—you'll still be able to force evaluation using toList, for example (although you should follow the advice in DaoWen's comment if you go that route).
The actual contents of underlying should never get used, though, so there's an easy fix—just make it an appropriately typed empty collection:
protected def underlying = Vector.empty[T]
Now if a user calls tree.force, they'll get a vector of labels, statically typed as a Traversable[T].
I accidentally ran into a situation like this (the example is simplified to isolate the problem):
abstract class Element(val other: Element)
case object First extends Element(Second)
case object Second extends Element(First)
object Main {
def main(arguments: Array[String]) {
val e1 = First
val e2 = Second
println("e1: "+e1+" e1.other: "+e1.other)
println("e2: "+e2+" e2.other: "+e2.other)
}
}
Anyone would like to guess the output? :-)
e1: First e1.other: Second
e2: Second e2.other: null
The output makes kind of sense. Apparently at the time the Second object is created, the First one does not yet exist, therefore null is assigned. The problem is... It's so wrong! It took me a couple of hours to track this one down. Shouldn't the compiler tell something about this?
Interestingly, when I tried to run the thing as a Scala script (the same code, minus object Main and def main lines, and closing }s), I got an infinite sequence (not really infinite - at some point the list stops, I guess due to some limitation on the depth of Exception traces, or something) of exceptions like this:
vilius#blackone:~$ scala 1.scala
...
at Main$$anon$1.Main$$anon$$Second(1.scala:4)
at Main$$anon$1$First$.<init>(1.scala:3)
at Main$$anon$1.Main$$anon$$First(1.scala:3)
at Main$$anon$1$Second$.<init>(1.scala:4)
at Main$$anon$1.Main$$anon$$Second(1.scala:4)
at Main$$anon$1$First$.<init>(1.scala:3)
...
I'd love to get something at least as informative during runtime...
Ok. I finished my rant. Now I guess I should ask something. :)
So, could you recommend any nice design for case objects pointing one to another? By the way, in my real situation there are several objects pointing to the next and previous instances in circular way (the last one points to the first one and vice versa).
Using Scala 2.8.1-final
EDIT:
I found a solution for my main problem:
abstract class Element {
val other: Element
}
case object First extends Element {
val other = Second
}
case object Second extends Element {
val other = First
}
This seems to work in compiled version (but not as a Scala script!). Could anyone shed some light on what's going on here?
EDIT2: This works as a script (the same thing, just using defs):
abstract class Element { def other: Element }
case object First extends Element { def other = Second }
case object Second extends Element { def other = First }
The usual way is like this (changed nesting so you can paste it into the REPL):
object Main{
abstract class Element(other0: => Element) {
lazy val other = other0
}
case object First extends Element(Second)
case object Second extends Element(First)
def main(arguments: Array[String]) {
val e1 = First
val e2 = Second
println("e1: "+e1+" e1.other: "+e1.other)
println("e2: "+e2+" e2.other: "+e2.other)
}
}
That is, take a by-name parameter and stick it into a lazy val for future reference.
Edit: The fix you found works because objects are themselves lazy in that you can refer to them but they don't get created until you use them. Thus, one object is free to point itself at the other without requiring that the other one has been initialized already.
I'd like to write a type alias to shorten, nice and encapsulated Scala code.
Suppose I got some collection which has the property of being a list of maps, the value of which are tuples.
My type would write something like List[Map[Int, (String, String)]], or anything more generic as my application allows it. I could imagine having a supertype asking for a Seq[MapLike[Int, Any]] or whatever floats my boat, with concrete subclasses being more specific.
I'd then want to write an alias for this long type.
class ConcreteClass {
type DataType = List[Map[Int, (String, String)]]
...
}
I would then happily use ConcreteClass#DataType everywhere I can take one, and use it.
Now suppose I add a function
def foo(a : DataType) { ... }
And I want to call it from outside with an empty list.
I can call foo(List()), but when I want to change my underlying type to be another type of Seq, I'll have to come back and change this code too. Besides, it's not very explicit this empty list is intended as a DataType. And the companion object does not have the associated List methods, so I can't call DataType(), or DataType.empty. It's gonna be even more annoying when I need non-empty lists since I'll have to write out a significant part of this long type.
Is there any way I can ask Scala to understand my type as the same thing, including companion object with its creator methods, in the interest of shortening code and blackboxing it ?
Or, any reason why I should not be doing this in the first place ?
The answer was actually quite simple:
class ConcreteClass {
type DataType = List[String]
}
object ConcreteClass {
val DataType = List
}
val d = ConcreteClass.DataType.empty
This enables my code to call ConcreteClass.DataType to construct lists with all the methods in List and little effort.
Thanks a lot to Oleg for the insight. His answer is also best in case you want not to delegate to List any call to ConcreteClass.DataType, but control precisely what you want to allow callers to do.
What about this?
class ConcreteClass {
type DataType = List[String]
}
object DataType {
def apply(): ConcreteClass#DataType = Nil
}
//...
val a = DataType()