Error with mixins in Scala - scala

I'm just learning Scala, and I have these three files:
abstract class Animal() {
name
sound
}
class Dog(n : String) extends Animal {
name = n
val sound = "Boof"
}
trait Speaking extends Animal {
def speak(n : String, s : Sound) : String = {
println(s + "! I'm " + n + "!")
}
}
In my main method, I have the following code:
d = new Dog("Maddie") with Speaking
println(d.speak)
When I run this code, I get error: not found: value d

Put val before d if you haven't declared it before.

I think it should be something like this:
abstract class Animal() {
def name: String // You need a type(String) and a qualifier(def)
def sound: String // the same
}
class Dog(n : String) extends Animal {
// Type is not obligatory here, as it is inherited from Animal.
// But you still need a qualifier(val)
val name = n
val sound = "Boof"
}
trait Speaking extends Animal {
// This method doesn't need those params,
// since this trait extends Animal,
// so it has access to name and sound defined there.
def speak: String = {
sound + "! I'm " + name + "!"
}
}
Your main method remains the same.

Related

Companion objects in scala

can any one explain the following output. I have a simple Scala code like this..
object compOrNotTest {
def main(args: Array[String]) {
var emp = new Employee("tom", 20)
println(emp)
println(Employee.adult(emp))
Employee.printName("Roland", 38)
var emp2 = new Employee("Harry", 37)
Employee.printName(emp2)
}
}
class Employee(name: String, age: Int) {
val ageOfEmplyedd: Int = age
val nameEmp: String = name
override def toString() = this.name + " age : " + this.age
def printName() {
println("name is in Class " + nameEmp)
}
}
object Employee {
def adult(emp: Employee) = {
if (emp.ageOfEmplyedd > 18)
true
else
false
}
def printName(name: String, age: Int) = {
val emp1 = new Employee(name, age)
println("Name is : " + emp1.printName())
}
def printName(emp1: Employee) = {
//val emp1 = new Employee(name, age)
println("Name is : "+ emp1.printName())
}
}
And the output I am getting is
tom age : 20
true
name is in Class Roland
Name is : ()
name is in Class Harry
Name is : ()
My question is that why , when I am calling from Companion object I am getting only Name is : (). I am expecting something like Name is : name is in Class Roland. Please help me out to understand the how scala works in this case. Thanks a lot
The return type of Employee.printName (in class Employee) is Unit. This is because this function was declared using procedure syntax (a function declaration with no = sign in it, which has been deprecated and which will no longer be supported in a future version of Scala) that has an associated return type of Unit. The Unit value that is returned is represented in Scala as ().
The following function declarations are equivalent:
// Using (soon-to-be-deprecated) procedure syntax.
def printName() {
println("name is in Class " + nameEmp)
}
// Using an explicit return type.
def printName(): Unit = {
println("name is in Class " + nameExp)
}
// Using an inferred return type (note "=" in declaration). The last statement is the call
// to println, which returns Unit, so a return type of Unit is inferred.
def printName() = {
println("name is in Class " + nameExp)
}
If you wanted to return the string that was printed, you would need something like this:
def printName() = {
val s = "name is in Class " + nameEmp
println(s)
s
}
Or, using an explicit return type, instead of inferring it from the last statement:
def printName(): String = {
val s = "name is in Class " + nameEmp
println(s)
s
}

Class A cannot be cast to Class A after dynamic loading

Let's say I have:
object GLOBAL_OBJECT{
var str = ""
}
class A(_str: String){
GLOBAL_OBJECT.str = _str
}
and I would like to create 2 copies of GLOBAL_OBJECT (for tests), so I am using different classloader to create obj2:
val obj1 = new A("1")
val class_loader = new CustomClassLoader()
val clazz = class_loader.loadClass("my.packagename.A")
val obj2 = clazz.getDeclaredConstructor(classOf[String]).newInstance("2")
println("obj1.getSecret() == " + obj1.getSecret()) // Expected: 1
println("obj2.getSecret() == " + obj2.asInstanceOf[A].getSecret()) // Expected: 2
which results following error:
my.packagename.A cannot be cast to my.packagename.A.
IntelliJ Idea seems to do it correctly, I can run obj2.asInstanceOf[A].getSecret() in "expression" window during debug process without errors.
PS. I have seen similar questions, but I could not find any not regarding loading class from .jarfile.
You're not going to be able to get around Java's class casting, which requires strict typing, within the same ClassLoader. Same with traits/interfaces.
However, Scala comes to the rescue with structural typing (a.k.a. Duck Typing, as in "it quacks like a duck.") Instead of casting it to type A, cast it such that it has the method you want.
Here's an example of a function which uses structural typing:
def printSecret(name : String, secretive : { def getSecret : String } ) {
println(name+".getSecret = "+secretive.getSecret)
}
And here's sample usage:
printSecret("obj1", obj1) // Expected: 1
printSecret("obj2", obj2.asInstanceOf[ {def getSecret : String} ]) // Expected: 2
You could, of course, just call
println("secret: "+ obj2.asInstanceOf[ {def getSecret : String} ].getSecret
Here's full sample code that I wrote and tested.
Main code:
object TestBootstrap {
def createClassLoader() = new URLClassLoader(Array(new URL("file:///tmp/theTestCode.jar")))
}
trait TestRunner {
def runTest()
}
object RunTest extends App {
val testRunner = TestBootstrap.createClassLoader()
.loadClass("my.sample.TestCodeNotInMainClassLoader")
.newInstance()
.asInstanceOf[TestRunner]
testRunner.runTest()
}
In the separate JAR file:
object GLOBAL_OBJECT {
var str = ""
}
class A(_str: String) {
println("A classloader: "+getClass.getClassLoader)
println("GLOBAL classloader: "+GLOBAL_OBJECT.getClass.getClassLoader)
GLOBAL_OBJECT.str = _str
def getSecret : String = GLOBAL_OBJECT.str
}
class TestCodeNotInMainClassLoader extends TestRunner {
def runTest() {
println("Classloader for runTest: " + this.getClass.getClassLoader)
val obj1 = new A("1")
val classLoader1 = TestBootstrap.createClassLoader()
val clazz = classLoader1.loadClass("com.vocalabs.A")
val obj2 = clazz.getDeclaredConstructor(classOf[String]).newInstance("2")
def printSecret(name : String, secretive : { def getSecret : String } ) {
println(name+".getSecret = "+secretive.getSecret)
}
printSecret("obj1", obj1) // Expected: 1
printSecret("obj2", obj2.asInstanceOf[ {def getSecret : String} ]) // Expected: 2
}
}
Structural typing can be used for more than one method, the methods are separated with semicolons. So essentially you create an interface for A with all the methods you intend to test. For example:
type UnderTest = { def getSecret : String ; def myOtherMethod() : Unit }
One workaround to actually run some method from dynamically delivered object instead of casting it is to use reflection in order to extract particular method, from new class and then invoke it on our new object instance:
val m2: Method = obj2.getClass.getMethod("getSecret")
m2.invoke(obj2)
The class file that contains obj2.asInstanceOf[A].getSecret() should be reloaded by CustomClassLoader, too.
And you must not use any class that references to A unless you reload the class by the same class loader that reloads A.

How do I access a class field from a mixed in method?

I'm playing around with mixins and traits in Scala and I've come across a small issue, how do I (without overriding) access a class field from a mixin?
Here's my code:
trait Friend {
def getHelp() = "Gets help"
}
trait Speak {
def speak(): String
}
class Person(var name: String) extends Speak with Friend {
override def speak() = s"Hello, I am $name"
}
class Dog(var name: String) extends Speak with Friend {
override def speak() = "woof woof!"
}
class Cat(var name: String) extends Speak {
override def speak() = "meow!"
}
Nothing too special really, but now I mix Friend into an object of Cat
val felix = new Cat("Felix") with Friend
println(felix.getHelp) // prints "Gets help"
How would I write it so that instead of it saying "Gets help" it says "Felix gets help"?
That is, getting the value from the name field without having to extend Friend at the class definition? (I don't want all instances of Cat to also be a Friend)
On the fly:
val fred = new Cat("Fred") with Friend {
override def getHelp() = {
name + " " + super.getHelp()
}
}
println(fred.getHelp())
or using another trait:
trait FriendWithName extends Friend {
var name: String
override def getHelp() = {
name + " " + super.getHelp()
}
}
val barney = new Cat("Barney") with FriendWithName
println(barney.getHelp())
or without trait Friend altogether:
val wilma = new Cat("Wilma") {
def getHelp() = {
name + " gets help"
}
}

Scala - Typeclass example. How to explain the benefits?

So I was showing a coworker/friend an example of the typeclass pattern in Scala. It looks like this:
case class Song(name: String, artist: String)
case class Address(street: String, number: Int)
trait LabelMaker[T] {
def output(t: T): String
}
object LabelMaker {
implicit object addressLabelMaker extends LabelMaker[Address] {
def output(address: Address) = {
address.number + " " + address.street + " street"
}
}
implicit object songLabelMaker extends LabelMaker[Song] {
def output(song: Song) = {
song.artist + " - " + song.name
}
}
def label[T : LabelMaker](t: T) = implicitly[LabelMaker[T]].output(t)
}
Which can be used like this:
import LabelMaker._
println(label(new Song("Hey Ya", "Outkast"))) // Outkast - Hey Ya
println(label(new Address("Smithsonian", 273))) // 273 Smithsonian street
It's not the best example, and in retrospect I wish I'd come up with a better one. Upon showing him, he responded with a counter example, and asked what benefits the typeclass pattern actually brings to the table:
case class Song(name: String, artist: String)
case class Address(street: String, number: Int)
object LabelMaker {
def label(address: Address) = {
address.number + " " + address.street + " street"
}
def label(song: Song) = {
song.artist + " - " + song.name
}
}
import LabelMaker._
println(label(new Song("Hey Ya", "Outkast"))) // Outkast - Hey Ya
println(label(new Address("Smithsonian", 273))) // 273 Smithsonian street
I struggled to answer that properly, and it made me realise I don't quite understand the gains made 100%. I understand their implementation and very localized benefits when someone else uses them, but to actually succinctly explain them is quite difficult. Can anyone help me? And perhaps extend on my example to really show the benefits.
Typeclasses capture the notion of retroactive extensibility. With static method overloads, you have to define them all at once in one place, but with typeclasses you can define new instances anytime you want for any new types in any modules.
For e.g.
object LabelMaker {
// ... your original cases here ...
def label[T : LabelMaker](t: T) = implicitly[LabelMaker[T]].output(t)
}
// somewhere in future
object SomeModule {
import LabelMaker._
case class Car(title: String)
implicit object carLabelMaker extends LabelMaker[Car] {
def output(car: Car) = car.title
}
}
object Main extends App {
import LabelMaker._
import SomeModule._
println(label(Car("Mustang")))
}
Type inference and composition of type-classes:
implicit def tupleLabel[A: LabelMaker,B: LabelMaker] = new LabelMaker[(A,B)]{
def output(tuple: (A,B)) =
implicitly[Label[A]].label(tuple._1) + " and " + implicitly[Label[B]].label(tuple._2)
}
This is obviously useful and will not work in the Java version of your co-worker.

Scala: Can I reproduce anonymous class creation with a factory method?

As far as I understand it, Scala creates an anonymous class if I create a class using the new keyword and follow the class name with a constructor:
class MyClass {
def doStuff() {
// ...
}
}
val mc = new MyClass {
doStuff()
}
The nice thing being that all the code in the constructor is in the scope of the new object.
Is there a way I can reproduce this syntax where the class is created by a factory method rather than the new keyword? i.e. make the following code work:
val mf = new MyFactory
val mc = mf.MyClass {
doStuff()
}
I can't find a way to do it but Scala has so much to it that this might be pretty easy!
Using an import as suggested by #Ricky below I can get:
val mf = MyFactory;
val mc = mf.MyClass
{
import mc._
doStuff()
}
(Where the blank line before the block is needed) but that code block is not a constructor.
You can do this, but you still have to keep the new keyword, and create the nested class as a path-dependent type:
class Bippy(x: Int) {
class Bop {
def getIt = x
}
}
val bip = new Bippy(7)
val bop = new bip.Bop
bop.getIt // yields 7
val bop2 = new bip.Bop{ override def getIt = 42 }
bop2.getIt // yields 42
I don't think it's possible. However, a common pattern is to add a parameter to factory methods which takes a function modifying the created object:
trait MyClass {
var name = ""
def doStuff():Unit
}
class Foo extends MyClass {
def doStuff() { println("FOO: " + name) }
}
trait MyClassFactory {
def make: MyClass
def apply( body: MyClass => Unit ) = {
val mc = make
body(mc)
mc
}
}
object FooFactory extends MyClassFactory {
def make = new Foo
}
You can then create and modify instance with a syntax close to your example:
val foo = FooFactory { f=>
f.name = "Joe"
f.doStuff
}
It sounds like you're just looking to mix in a trait. Instead of calling myFactoryMethod(classOf[Foo]] which ideally would do (if Scala permitted it):
new T {
override def toString = "My implementation here."
}
you can instead write
trait MyImplementation {
override def toString = "My implementation here."
}
new Foo with MyImplementation
However, if you are just looking to get the members of the new object accessible without qualification, remember you can import from any stable identifier:
val foo = new Bar
import foo._
println(baz) //where baz is a member of foo.