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.
Is there a way in scala to get list of all objects(by object I mean scalas object) that derive from specified abstract class?
something like that:
abstract class A
object B extends A //in different file
object C extends A //in different file
def findObjectsDerivingFromA(): Seq[A] //which will give result: Seq(B, C)
I know from here : Can I get a compile-time list of all of the case objects which derive from a sealed parent in Scala?
that it's possible with sealed base trait/class but in my case objects B and C will be pretty complex so I need to have them in different files.
edit:
I've changed method name because previous one was misleading.
I'm building a set of objects to represent the data abstraction layer sitting between my angularjs application and the backend API. I'm using coffeescript for this (partly to learn coffeescript, partly because I am enjoying their class implementation as I originally hail from a c++ and java background from Days of Yore).
So I have something like
Class Animal
#_cache: {}
...stuff...
Class Dog extends Animal
#_cache: {}
and so on. The issue (which is clearly a syntactic sugar thing) is that I'd like to have all concrete subclasses of Dog have their own instance of the cache. I can handle it either by how I did it above (just override the property), or by replacing that cache with something like #_cache[#constructor.name] = {}, and writing cache accessor functions instead of just directly interacting with it.
Basically, the pattern I want to express is: "Property #{name} should be a class-level (or static) property on this object, and all extending classes should have their own instance of this property", without manually having to do that on each child type. Is there a reasonable pattern to do this?
I have a suggestion, using the dynamic pointer of an instance to its own class: #constructor
In this example, the cache is initialized at first instance creation, and populated in the constructor itself.
class Animal
# is is just here to distinguish instances
id: null
constructor:(#id) ->
# #constructor aims at the current class: Animal or the relevant subclass
# init the cache if it does not exists yet
#constructor._cache = {} unless #constructor._cache?
# now populates the cache with the created instance.
#constructor._cache[#id] = #
class Dog extends Animal
# no need to override anything. But if you wish to, don't forget to call super().
# creates some instances
bart = new Animal 1
lucy = new Dog 1
rob = new Dog 2
console.log "animals:", Animal._cache
# prints: Object {1=Animal}
console.log "dogs:", Dog._cache
# prints: Object {1=Dog, 2=Dog}
see this fiddle (results on console)
I am new to Scala and I could not really find a lot about the type keyword. I am trying to understand what the following expression may mean:
type FunctorType = (LocalDate, HolidayCalendar, Int, Boolean) => LocalDate
FunctorType is some kind of an alias, but what does it signify?
Actually the type keyword in Scala can do much more than just aliasing a complicated type to a shorter name. It introduces type members.
As you know, a class can have field members and method members. Well, Scala also allows a class to have type members.
In your particular case type is, indeed, introducing an alias that allows you to write more concise code. The type system just replaces the alias with the actual type when type-checking is performed.
But you can also have something like this
trait Base {
type T
def method: T
}
class Implementation extends Base {
type T = Int
def method: T = 42
}
Like any other member of a class, type members can also be abstract (you just don't specify what their value actually is) and can be overridden in implementations.
Type members can be viewed as dual of generics since much of the things you can implement with generics can be translated into abstract type members.
So yes, they can be used for aliasing, but don't limit them to just this, since they are a powerful feature of Scala's type system.
Please see this excellent answer for more details:
Scala: Abstract types vs generics
Yes, the type alias FunctorType is just a shorthand for
(LocalDate, HolidayCalendar, Int, Boolean) => LocalDate
Type aliases are often used to keep the rest of the code simple: you can now write
def doSomeThing(f: FunctorType)
which will be interpreted by the compiler as
def doSomeThing(f: (LocalDate, HolidayCalendar, Int, Boolean) => LocalDate)
This helps to avoid defining many custom types that are just tuples or functions defined on other types, for example.
There are also several other interesting use cases for type, as described for example in this chapter of Programming in Scala.
I liked the answer from Roland Ewald since he described with a very simple use case of type alias, and for more detail introduced a very nice tutorial.
However, since another use case is introduced in this post named type members, I would like to mention the most practical use case of it, which I liked very much:
(this part is taken from here:)
Abstract Type:
type T
T above says that this type that is going to be used, is unknown yet, and depending on the concrete subclass, it will be defined.
The best way always for understanding the programming concepts is providing an example:
Suppose you have the following scenario:
Here you will get compilation error, because eat method in classes Cow and Tiger do not override the eat method in class Animal, because their parameter types are different. It's Grass in class Cow, and Meat in class Tiger vs. Food in class Animal which is super class and all subclasses must conform.
Now back to type abstraction, by the following diagram and simply adding a type abstraction, you can define the type of the input, in according subclass itself.
Now look at following codes:
val cow1: Cow = new Cow
val cow2: Cow = new Cow
cow1 eat new cow1.SuitableFood
cow2 eat new cow1.SuitableFood
val tiger: Tiger = new Tiger
cow1 eat new tiger.SuitableFood // Compiler error
Compiler is happy and we improve our design. We can feed our cow with cow.SuitableFood and compiler prevent us with feeding out cow with the food which is suitable for Tiger. But what if we want to make difference between the type of cow1 SuitableFood and cow2 SuitabeFood. In another word, it would be very handy in some scenarios if the path by which we reach to the type (of course via object) does basically matter. Thanks to the advanced features in scala, it is possible:
Path-dependent types:
Scala objects can have types as members. The meaning of the type, depends on the path you use to access it. The path is determined by the reference to an object (aka an instance of a class).
In order to implement this scenario, you need to define class Grass inside the Cow, i.e., Cow is the outer class and Grass is the inner class. The structure will be like this:
class Cow extends Animal {
class Grass extends Food
type SuitableFood = Grass
override def eat(food: this.SuitableFood): Unit = {}
}
class Tiger extends Animal {
class Meat extends Food
type SuitableFood = Meat
override def eat(food: this.SuitableFood): Unit = {}
}
Now if you try to compile this code:
1. val cow1: Cow = new Cow
2. val cow2: Cow = new Cow
3. cow1 eat new cow1.SuitableFood
4. cow2 eat new cow1.SuitableFood // compilation error
On line 4 you will see an error because Grass is now an inner class of Cow, therefore, to create an instance of Grass, we need a cow object and this cow object determines the path. So 2 cow objects give rise to 2 different path.
In this scenario, cow2 only wants to eat food especially created for it. So:
cow2 eat new cow2.SuitableFood
Now everybody is happy :-)
Just an example to see how to use "type" as alias :
type Action = () => Unit
The definition above defines Action to be an alias of the type of procedures(methodes) that take an empty parameter list and that return Unit.
If I want a serialization-safe singleton, should I prefer
case object Foo
or
object Foo extends Serializable
?
I think this depends on how you plan to use this object. Case objects are generally used with case classes to represent some kind of initial or terminal object in an algebraic data type, eg Nil or None. Regular objects usually are companions for classes to hold static methods like singleton and factory methods.
If you're planning using this object with other classes, serializing it, and maybe using it in pattern matching, defining it as a case object seems more natural to me.