Trying to implement a UUID(random unique identifier) generated from a method - scala

New to scala, what is the best way to implement this method. I am trying to get this value output from the method below and assign it to a case class. Bit rusty on the OOP practices.
/** A container for storing car table fields */
case class car(
UUID??
color:String,
model:String,
type:String,
)
Basicaly my question what is the best way to create an instance of the below rand value to the case class car above. Create another class and call it or implement with in the same scala class?
def rand = new Random()
def randomClockSeqAndNodeFields = {
var lsb: Long = 0
lsb |= 0x8000000000000000L // variant (2 bits)
lsb |= ( rand.synchronized { rand.nextLong } & 0x3FFFFFFFFFFFFFFFL)
lsb
}

I suggest, since UUID is a java supported type :
/** A container for storing car table fields */
case class car(
uuid: UUID = UUID.randomUUID(),
color:String,
model:String,
type:String,
)

One way to organize this code is to define a companion object:
object Car {
def rand = new Random()
def randomClockSeqAndNodeFields = { ... }
}
case class Car(
UUID: Long = Car.randomClockSeqAndNodeFields,
color: String,
model: String,
make: String
)
You can call your method inside the declaration of your case class, and that method will, by default, be called for every instance of the class. Note that I capitalized the class name to follow standard naming conventions, and I renamed type to make because type is a keyword.
To create a Car instance:
val myCar = Car(color="black", model="wrangler", make="jeep")
The creation of every Car instance, if you don't explicitly pass in a value for the UUID parameter, will call randomClockSeqAndNodeFields, generating a new UUID for that car. Alternatively, you could define Car as...
case class Car(
UUID: Long,
color: String,
model: String,
make: String
)
...in which case you'd have to explicitly call randomClockSeqAndNodeFields every time you create an instance:
val myCar = Car(Car.randomClockSeqAndNodeFields, "black", "wrangler", "jeep")

Related

How to unpack a parent object into a extended child constructor?

I am looking to splat an object into a constructor that accepts all pairs in that object.
case class Cat(name: String)
case class PetPersian(name: String, price: Number)
val c1 = Cat(name = "Meowth")
val c2 = PetPersian(
c1, // this is what I am trying to reuse.
price = 10000
)
You can create a custom constructor in the companion object which will make the code work.
object PetPersian {
def apply(cat: Cat, price: Number): PetPersian = PetPersian(cat.name, price)
}
If there is a need to accept a number of different types in the constructor, declare a common trait for those types or use a typeclass.
If you want to make it work with any object with a name field it can be done using a structural type which has performance and other issues and is not recommended.
object PetPersian {
def apply(n: { def name: String }, price: Number): PetPersian = PetPersian(n.name, price)
}

Difference Scala Class Declaration

I want to ask what's the difference between these two Class Declarations below.
class Person(name: String, age: Int)
or
class Person() {
var name: String = ""
var age: Int = 0
}
class Person(name: String, age: Int)
name and age are constructor parameters. As such they are:
required - in order to create a Person instance
immutable - the values cannot be changed
private - (by default) and cannot be accessed via a class instance
class Person() {
var name: String = ""
var age: Int = 0
}
name and age are class data members. They are:
not specified during construction - but are given the same default values for every Person instance
mutable - because they are var variables
public - (by default) and can be accessed and modified via a class instance
So, what's the difference? Almost everything.
The first declaration uses name and age as constructor arguments, but they do not become members of the class, that is you can't write person.name.
For a beginner, the second line can be considered a more complicated way to write class Person(var name: String = " ", var age: Int = 0). It actually doesn't translate to exactly the same thing: your version creates a class that has a single constructor argument and two public variables, while mine has a constructor with 2 arguments that have default values. Unless you have a good reason to declare it your way, it's usually better to write:
val person = new Person("Andrew", 11)
than
val person = new Person()
person.name = "Andrew"
person.age = 11
which is what your second version would force you to do.
Note that in Scala, you will mostly be using values (constants) and not variables, so you'd actually typically use class Person(val name: String = " ", val age: Int = 0). For simple data types like this, people typically use a case class:
case class Person(name: String, age: Int)
In this case, both argument are considered public and immutable. The only way to modify a person's name is to create another instance of Person with the new name:
val andrew = Person("Andrew", 11)
val will = andrew.copy(name="Will") # Will is also 11
Case classes will automatically give you proper equals and hashCode implementation, as well as the copy method I used above. You can easily find more infos about them on the internet.

Set an implicit function return in Scala

I am writing DSL (domain specific language for my code).
The code is:
class NeuronGroupDSL(identifier: String)(implicit network: N2S3SimulationDSL ) // declared values which must be provided by the user, [we can just give a default constructor to this]
{
implicit val sizeDefault : Int = 28 // added the implicit default value for the setNumberOfNeurons method
val id: String = identifier // We can add a default constructor with the Id and the network to this too allow user to skip this part
var neuronGroup: Option[NeuronGroupRef] = None // this variable stores all the information by using the get property and a associated function with it
private var neuronParameters: Seq[(Property[_], _)] = Seq()
private var neuronModel: NeuronModel = _
/**Properties of the NeuronGroupDSL **/
// Added a default size to the size variable
def ofSize(implicit size: Int): NeuronGroupDSL = {
this.neuronGroup.get.setNumberOfNeurons(size)
this
}
// Give user the opportunity to choose the type of available models by the help of pattern matching
/**Neuron Model:
1. Linear leaky integrate-and-fire model
2. FitzHugh-Nagumo model
3. Izhikevich model
**/
def modeling(model: NeuronModel): NeuronGroupDSL = {
this.neuronModel = model
this.neuronGroup.get.setNeuronModel(model, this.neuronParameters)
this
}
//we can define a default property the neuron group model here
def withParameters(properties: (Property[_], _)*): NeuronGroupDSL = {
this.neuronParameters = properties
this.neuronGroup.get.setNeuronModel(this.neuronModel, properties)
this
}
}
As you can see the definitions ofSize modeling withParameters have the same return type, so is it possible to implicitly define their return type and define these functions without their return part ?
Please help me I want to minimize the code as much as possible.
I too want to know that is it possible to use case class , concise lambda syntax in this code to further minimize it.
You can simply drop the return type, it will be inferred automatically:
def ofSize(implicit size: Int) = {
neuronGroup.get.setNumberOfNeurons(size)
this
}

How to auto generate object when the class get no params

So i have simple class named Person, this class have several fields:
class person {
val name:String
val abe:Int
def generateRandom(): Person {
// Here i want to generate Person and return
}
}
So as you can see i want my class will have the option to generate random Person but i don't want to pass any params to my class, i want it to be auto.
So how can i create new Person object inside this generateRandom method and return it with both name and age fields ?
Any suggestions how to implement it ?
You use val for name and age, so there's no other way - you have to set then in constructor. However you can make constructor private and move generator method to companion object (because it can access private constructor). The code would look like this:
class Person private (val name: String, val age: Int)
object Person {
def generateRandom(): Person = {
val randomName = ...
val randomAge = ...
new Person(randomName, randomAge)
}
}
//new Person("asdas", 3) not possible
val person = Person.generateRandom()
println(person.name, person.age)
I think you need to have param: String = null in your parentheses. With the accompanied if(param == null)...
Scala default parameters and null
It seems very simple.
Just return the new Person object from the method, adding some random value to Name and Age.

How to store an Enumeration within a MongoCaseClassField in Lift Record?

Using Lift Record, when I try to retrieve the MongoDB entry below, a NullPointerException is raised when the .asHtml method of MongoCaseClassField is called.
object MyEnumeration extends Enumeration {
val A, B, C = Value
}
case class MyCaseClass(en: MyEnumeration.Value)
class MyRecord extends MongoRecord[MyRecord] with MongoId[MyRecord] {
def meta = MyRecord
object fail extends MongoCaseClassField[MyRecord, MyCaseClass](this)
}
object MyRecord extends MyRecord with MongoMetaRecord[MyRecord]
However this works fine if I use String instead of Enumeration. Is there any way to use enumerations in case class fields or should use a different type of field?
At the time of writing mongoDB doesn't place nice with scala enums, I use a decorator method as a work around.
Say you have this enum:
object EmployeeType extends Enumeration {
type EmployeeType = Value
val Manager, Worker = Value
}
and this mongodb record:
import EmployeeType._
case class Employee(
id: ObjectId = new ObjectId
)
In your mongoDB, store the integer index of the enum instead of the enum itself:
case class Employee(
id: ObjectId = new ObjectId,
employeeTypeIndex: Integer = 0
){
def employeeType = EmployeeType(employeeTypeIndex); /* getter */
def employeeType_=(v : EmployeeType ) = { employeeTypeIndex= v.id} /* setter */
}
The extra methods implement getters and setters for the employee type enum.
I am quite certain that this will only work with native types like String, Int, Float, Double, Boolean, etc, but not Enumerations. I am really certain that this is due to serialization.