How to assign a value to an object (instance) itself? - class

For example, in the case of a list object,
a = list([1, 2, 3])
print(a)
>>> [1, 2, 3]
When I call only the object (instance) (without parentheses), the value is returned immediately.
So to assign a value to the object itself, like a list,
I created the following class and assigned a value to self itself.
class Test:
def __init__(self, x):
self = x
a = Test(1)
print(a)
>>> <__main__.Test object at 0x0000019E422A8990>
The object's address is returned, the value 1 is not returned.
Just as I can call an instance like a function if I define call(),
Is there a method that sets a value to be returned when an instance is called like a list?
Summary of questions:
How can I make it return a value, not an object, when only the instance is called?

Related

new to scala anyone explain the code for me?

def indexOf[T](seq: Seq[T],value: T, from: Int):Int={
for(i<-from until seq.length){
if(seq(i)== value) return i
}
-1
}
Anyone explain to me indexOf[T] meaning? And what does (seq:Seq[T],value:T) do?
def indexOf - This is a method. We'll call it indexOf.
[T] - This method will make reference to an unspecified type. We'll call it T.
(seq:Seq[T], value:T, from:Int) - This method will take 3 passed parameters:
variable seq which is a Seq of elements of type T
variable value which is a single value of type T
variable from which is a single value of type Int
:Int - This method returns a value of type Int.
= { - Mehod code begins here.
This is related to Scala generics.
https://docs.scala-lang.org/tour/generic-classes.html
In simple terms, here, T acts as a place holder for any data type.
The indexOf function takes a generic T, which during runtime can be a Integer, String or custom Employee object.
For example in the sequence, you can pass a Seq of Employee or String and same data type value.
By using generics, for your example, you dont have to create different indexOf function for every other data type.
How to call indexOf? As below:
val index = indexOf[String](stringSeq, "searchThis", 0)
or
val index = indexOf[Employee](employeeSeq, empObj, 0)
This method is what we call a parametric method in scala.
Parametric methods in Scala can be parameterized by type as well as
value. The syntax is similar to that of generic classes. Type
parameters are enclosed in square brackets, while value parameters are
enclosed in parentheses.
Since T is a generic type, that means that indexOf method can be called on a variety of types.
Your method indexOf[T] takes a type parameter T and value parameters seq, value and from.
When calling your method, you can either set explicitly the type you will be manipulating by replacing the T by your concrete type (see example 1), or let the compiler work for you (type inference) based on the parameter type of your param seq and value. (see example 2)
Example 1
val index = indexOf[Int](Seq(3, 5, 4), 4, 0)
Example 2
val index = indexOf(Seq("alice", "bob", "yo"), "bob", 1)

class needs to be abstract since its members are not instantiated

I am trying to create a class rat having parameters "value" and "dimensions". Rat has a member "fitness". I want this member to be initialized by constructor, but declaring this member enforces it to be explicitly instantiated.
This is a class rat having a member fitness. I have declared but not defined the member as I want to get it through constructor.
class rat(value:Int,dimensions:Int){
var fitness:Int
def rat(){
fitness=sol_fit()
}
def sol_fit():Int={
var f=value*dimensions
f
}
}
This looks like a really bad design for a class. I question nearly everything about it. But it's easy enough to make it compile: just give the var a default value.
var fitness:Int = _
Now it compiles but the value of fitness will remain at default (0 in this case) because you have defined the method to calculate the proper fitness value but it is never invoked so the fitness value is unchanged.
But really, why go through all the rigamarole? Why not just initialize it with the calculated value? Why not var fitness:Int = sol_fit() or simply var fitness:Int = value*dimensions?
The constructor is the block following the class declaration, so it is OK to write this:
class rat(value: Int, dimensions: Int) {
val fitness: Int = value*dimensions
}
The expression value*dimensions will be computed when an instance of the class is created, and placed in the class memory as an Int value. When the fitness member is accessed, the value will be retrieved from the class memory and returned; it will not be re-computed.
If fitness had been declared using def rather than val, then the expression would be computed each time fitness was accessed.
If fitness had been declared using var then the value could be replaced with a new value, and any subsequent access to fitness would return the new value.

How to access member variables in nested case classes

I have this code:
case class L2JsonMapping(myTarget: Option[Int])
case class L1JsonMapping(l1: Option[L2JsonMapping])
case class JsonMapping(l0: Option[L1JsonMapping])
Assume that they have been initialized. Now how should I get "myTarget" assigned to "result" in the following function:
def function(in: JsonMapping): Int = {
val result = ?
...
}
Note that I also need to handle Option situation. Thanks.
You'll have to supply a default value to return in case one of the Options is None. Let's assume that default is 0 - if so, you can use:
def function(in: JsonMapping): Int = in.l0 // get Option[L1JsonMapping]
.flatMap(_.l1) // flatMap to get an Option[L2JsonMapping]
.flatMap(_.myTarget) // flatMap to get an Option[Int]
.getOrElse(0) // get value value or default
This uses Option.flatMap which you can read about in the ScalaDocs:
Returns the result of applying [the given function] f to this scala.Option's value if this scala.Option is nonempty. Returns None if this scala.Option is empty.
NOTE that this simply returns the value of myTarget - I'm assuming you're assigning it to result just to return result immediately - if so, that's redundant.

Basic Scala: Methods holding parameters?

I am reading the book Programming in Scala and in chapter 10 I had to write:
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
}
class ArrayElement(conts: Array[String]) extends Element {
def contents: Array[String] = conts
}
but the concept I don't catch here is how can I define a method that is holding a variable? As far as I know, methods return a value, it can be a computed value or an instance variable directly, but they can't hold a value. Am I forgetting a basic concept about the programming language that applies here too?
Try this out:
abstract class Foo { def bar: Int }
class Baz(val bar: Int) extends Foo
In Scala, you can implement methods by creating member variables with same name and same type. The compiler then adds a corresponding getter-method automatically.
The member variable and the getter-method are still two different things, but you don't see much difference syntactically: when you try to access it, its both just foo.bar, regardless of whether bar is a method or a member variable.
In your case
def contents: Array[String] = conts
is just an ordinary method that returns an array, an equivalent way to write the same thing would be
def contents: Array[String] = {
return conts
}
Since the array is mutable, you can in principle use this method to modify entries of your array, but the method itself is really just a normal method, it doesn't "hold" anything, it just returns reference to your array.
Edit: I've just noticed that conts is actually not a member variable. However, its still captured in the definition of the contents method by the closure-mechanism.

When overriding a trait, why the value is strange?

Demo scala code:
trait A {
val a = 3
val b = a + 2
}
trait B extends A {
override val a = 10
}
object X extends B
println(X.b)
It prints value: 2, why is it not 5 or 12?
To answer the why:
In Scala when you write
class A {
val a = 2
}
The value is initialized in the constructor of the class (the same behavior applies to traits and objects). Furthermore, superclasses are initialized before subclasses. This leads to the following behavior for your use case:
B is created (memory is reserved), with two variables a and b whose value is 0. Now the constructor of A is invoked. Because a is overwritten in a subclass and due to Scalas dynamic binding nature, it is not assigned with 2, but with the value of the subclass. You want to be it 10, but because this assignment happens in the constructor of B (which is not yet invoked) the default value 0 is assigned. Now, b is assigned. Because it is not overwritten, the value a+2 is chosen, where a is 0. Because the constructor of A is finished here, the constructor of B can be invoked, which assigns 10 to a.
Hence, a is 10 and b is 2.
To answer what to do against this behavior bug:
Don't use vals as long as you don't absolutely understand about the problems that can arise. Use defs or lazy vals instead, there values are not initialized in the constructor of a class and therefore can be easily overwritten. If you absolutely need a val in a trait, then make it final
It is possible to mark a var as initialization independent for the subclass, which can be done with var a: Type = _. This tells the compiler to not initialize this variable in the constructor of the defining class (but means that the value needs to stay mutable). It can then easily be assigned in the subclass. This gets important when the in the constructor of the superclass as method is called, that initializes a var:
class A {
f()
def f() = ()
}
class B extends A {
// don't initialize this var with anything else here or
// the later assignment will be overwritten
var b: Int = _
override def f() =
b = 5
}
new B().b // prints 5