Scala limitation on constructor-defined attributes - class

In Scala, it's possible to define class attributes in the constructor. But once you declare them there, it's not possible anymore to change the behavior (getters and setters), like you can when declaring in the class body?
Example:
class MyExample(var attribute : String)
{
def attribute() //trying to override getter <- doesn't work
}
class MyExample(theAttribute : String)
{
def attribute = theAttribute //overriding default accessor (was var)
}
If it's not possible, why is it so? It seems confusing when you show people that they can easily create attributes by setting var or val in constructor, and not care about getters and setters (they can change if they need), to ultimately find that, in fact, you should avoid using those kind of facilitations.

Let's for a moment imagine that it was possible to override the generated accessor-method:
class MyExample(var attribute : String)
{
def attribute() = attribute + "abc" // won't compile!
}
Without a further qualification it is impossible to tell whether the name attribute within method body refers to the class field or recursively to the method itself.
By design in Scala methods and fields belong to the same namespace, this, known as Uniform Access Principle, gives the ability to change an internal implementation without breaking the external interface.
An initial implementation could be:
class MyExample(val attribute : String)
Then changed onto:
class MyExample (attr :String) {
def attribute = attr toUpperCase
}
And then
class MyExample(var attribute : String)
Or
class MyExample(attr : String) {
def attribute = attr toUpperCase
def attribute_= (a : String) { attr = a + "abc" }
}
All without breaking any of the dependent code.
When field is defined as part of a constructor the automatically generated accessor-methods are syntactic sugar. The sugar eases quick prototyping and helps to keep the code concise. Nonetheless, whenever you want to add more substance you must use the full syntax.

Related

How can I return a scala "object" as if it's a class instance?

I have an abstract superclass with a variety of stateless implementations. It seems like the thing to do is make the abstract superclass a class, and make each implementation an object because I only ever need one of each.
This is a toy example, but it shows the compile error I’m getting:
// Tramsformer.scala
class Transformer {
def transform(value : String) : String
}
object Transformer {
getTransformer(String : name) : Transformer = {
name match {
case "upper" => UpperTransformer
// I'm getting "Cannot Resolve Symbol" on UpperTransformer,
// even though they're in the same package.
case _ => throw new IllegalArgumentException("...")
}
}
}
// ---
// UpperTransformer.scala is in the same package
object UpperTransformer extends Transformer {
override def transform(vlaue : String) = foo.toUpperCase()
}
I’m really shooting for some sort of dynamic dispatch on (dataProvider, desiredAction) here.
Then some class can call Transformer.getTransformer("upper").transform("stack-overflow") without making any unnecessary objects.
Any idea what I should be doing differently? Should I stop worrying about premature optimization and learn to love the instance?
The problem isn't visibility, it's that you simply do not define an object named UpperTransformer anywhere - only a class. If you replace class UpperTransformer with object UpperTransformer, your code should work fine.

Scala : Need to create a newInstance of a class using Reflection that takes paramaters

class Config(sourceName :String, storeClass :Class[_]) {
def store = storeClass.getConstructor(classOf[Configuration]).newInstance(sourceName)
def write(k :String, v :String) {
store.writeTo(k,v)
}
def read(k :String): Unit ={
store.readFrom(k)
}
def contains(k :String) :Boolean ={
store.isContains(k)
}
}
Here Configuration is a parent-abstract class whom are having some child classes.
So the 2nd parameter in class config, can be any child class Configuration.
And each child class takes a parameter while Initiating ie; sourceName.
storeClass.getConstructor(classOf[Configuration]).newInstance(sourceName)
This code above Return Type : Any , which create issue, since i need it to be of Type Configuration
def store :Configuration
to be of the Type Configuration, otherwise the read,write and contains won't work !
The getConstructor method selects a constructor that accepts parameters of the classes that you provide it. From your code it would appear that you want a constructor that accepts a String, so you probably want to do the following:
storeClass.getConstructor(classOf[String])
.newInstance(sourceName)
.asInstanceOf[Configuration]
But I'm not sure if that is the ideal solution to the problem you're trying to solve. Runtime reflection and Class[_] objects are not very Scala-esque...
Cast it with .asInstanceOf[Configuration]. When using reflection, you have to expect to break type safety.

What am I doing wrong? (With Scala's superclass parameters)

I have an parent class, and several child classes. What I want is when specific setter methods are called on instances of the child classes, a boolean value for "is synchronized" in the parent class is set to false. It should be possible to create child classes in either a synchronized or an unsynchronized state.
This is what I came up with:
class A(protected var isSync: Boolean) {
}
class B(var value:String, isSync: Boolean) extends A(isSync) {
override def value_=(value:String): Unit = {
this.isSync = false
this.value = value
}
}
Now, this doesn't compile for a number of reasons: the assignment of value to this.value is ambiguous; the var annotation already defines value_=; and this.isSync references the local constructor field isSync, instead of the (writable) parent field.
This question on Stack Overflow pointed out that I should use __value (or any name that isn't value) as a private var in the constructor, and define the setter myself. After some more tinkering, I came up with the following code that compiles and works:
class A(protected var isSync: Boolean) {
}
class B(private var __value: String, private val __isSync: Boolean)
extends A(__isSync) {
def value = __value
def value_=(value: String) = {
this.isSync = false
this.__value = value
}
}
However, this code feels so rancid that by now I suspect I'm making a (if not more) fundamental mistake. Could anyone please correct me?
Thus the concrete questions are:
Are there (and if, which) fundamental flaws in what I'm trying to implement? For some context: the objects, when changed, can (and probably have to) be synchronized with a server.
What is the right/best way to pass parameters to a class you extend?
What is the right/best way to override the setter generated by var (or generally provide your own setter implementation)?
About question 1: I guess that you want to track whether the object has been changed since last time it was copied to the server, don't you? That's sensible, as long as the copy on the server cannot be modified: otherwise ensuring consistency of the replica is more complex (replica consistency is the keyword for googling, but I wouldn't recommend it).
For clarity, I would talking about being clean or dirty - synchronized reminds me too closely of the synchronized Java statement.
About question 2, you don't need to make __isSync a private val (which will be stored in the class), you can leave it as a constructor parameter. As long as it is not used (other than in the invocation of A's constructor) __isSync should not take additional space in instances of B. I removed the private val annotation there, obtaining this code which compiles correctly as expected.
class A(protected var isSync: Boolean) {
}
class B(private var __value: String, __isSync: Boolean)
extends A(__isSync) {
def value = __value
def value_=(value: String) = {
this.isSync = false
this.__value = value
}
}
About aesthetics and question 3: I would simply avoid the double underscore. Similar examples from Programming in Scala (Sec 18.2) simply use shorter names. They also use private[this] to prevent access to the member from other instances of the same class. Finally, you can remove {} after the class decl. in this example (even if maybe not in your code).
Thus we'd get code like this, which is close to the examples I already mentioned:
class A(protected var isSync: Boolean)
class B(private[this] var v: String, sync: Boolean)
extends A(sync) {
def value = v
def value_=(value: String) = {
isSync = false
v = value
}
}

How do I declare a constructor for an 'object' class type in Scala? I.e., a one time operation for the singleton

I know that objects are treated pretty much like singletons in scala. However, I have been unable to find an elegant way to specify default behavior on initial instantiation. I can accomplish this by just putting code into the body of the object declaration but this seems overly hacky. Using an apply doesn't really work because it can be called multiple times and doesn't really make sense for this use case.
Any ideas on how to do this?
Classes and objects both run the code in their body upon instantiation, by design. Why is this "hacky"? It's how the language is supposed to work. If you like extra braces, you can always use them (and they'll keep local variables from being preserved and world-viewable).
object Initialized {
// Initalization block
{
val someStrings = List("A","Be","Sea")
someStrings.filter(_.contains('e')).foreach(s => println("Contains e: " + s))
}
def doSomething { println("I was initialized before you saw this.") }
}
scala> Initialized.doSomething
Contains e: Be
Contains e: Sea
I was initialized before you saw this.
scala> Initialized.someStrings
<console>:9: error: value someStrings is not a member of object Initialized
Initialized.someStrings
Rex has it right, I just wanted to point out a pattern I use a lot, that saves you from having to use vars, while avoiding namespace pollution by intermediate values.
object Foo {
val somethingFooNeeds = {
val intermediate = expensiveCalculation
val something = transform(intermediate)
something
}
}
If it makes you feel better, you can create some class with protected constructor and object will create singleton of this class:
sealed class MyClass protected (val a: String, b: Int) {
def doStuff = a + b
}
object MyObject extends MyClass("Hello", b = 1)
Also notice, that sealed stops other classes and objects to extend MyClass and protected will not allow creation of other MyClass instances.
But I personally don't see any problems with some code in the body of the object. You can also create some method like init and just call it:
object MyObject {
init()
def init() {
...
}
}
The body of object and class declarations IS the default constructor and any code placed in there will be executed upon first reference, so that is exactly the way to do it.

How to expose a constructor variable(sic!) as read-only?

I have this rather simple question about Scala. Given that i have to following class definition:
class Foo(var bar: Int)
The code which is able to construct an instance of Foo must be able to pass the initial value for bar. But if I define bar as var the User is also able to change its value at runtime which is not what I want. The User should only be able to read bar. bar itself is modified internally so a val is not an option.
Read-only for a property is easy, just create a getter method without the corresponding setter. It's also easy to make a private modifiable field.
Your biggest challenge here is the shared namespace, you want to be able to use the same name for:
the constructor param
the internal modifiable field
the public getter
the private setter
Sadly, this is not possible, and you need a distinct name for each role... something like this:
class Bippy(bop0: Int) {
private[this] var privatebop = bop0
//privatebop is ONLY EVER used by the following getter and setter:
private def bop_=(x:Int) = privatebop = x
def bar = privatebop
}
If you're not concerned about using named arguments, or with the name of the argument in Scaladoc, then this can be shortened even further:
class Bippy(private[this] var privatebop) {
//privatebop is ONLY EVER used by the following getter and setter:
private def bop_=(x:Int) = privatebop = x
def bop = privatebop
}
UPDATE
The cleanest method, arguably, which gives you back named parameters is to combine a factory with one of the above techniques:
object Bippy{
def apply(bop: Int) = new Bippy(bop)
}
Which can then be called as Bippy(42). Just the same as the regular constructor, but without the new keyword.