This question already has answers here:
How to check constructor arguments and throw an exception or make an assertion in a default constructor in Scala?
(2 answers)
Closed 7 years ago.
Suppose that I have the following class defined in Scala:
class ClassA(val n: Int) {
...
}
I want to limit this class instances to only those that have n between 5 to 10 using Factory Pattern. For example, In case I write something like:
val a = new ClassA(11)
This raises an exception with an appropriate error message, or at least it returns null or something. How can I achieve this behaviour?
Update:
It is possible to achieve this in java with Factory pattern.
Update2:
This questions seems to be answered here, notably with a verbose title though. I tweak the title and content to save the question being deleted, because of two reasons: 1) The example in this one is concise, 2) the provided answer by #Chris Martin explains briefly the way Factory pattern can be reached in Scala by Using Companion Objects.
The conventional way to write a factory in Scala is to define an apply method on the companion object.
Here's an example using Either (because null is never/rarely used in Scala, and exceptions are ugly):
class A private (n: Int) {
override def toString = s"A($n)"
}
object A {
def apply(n: Int): Either[String, A] =
if (n < 5) Left("Too small")
else if (n > 10) Left("Too large")
else Right(new A(n))
}
A(4) // Left(Too small)
A(5) // Right(A(5))
A(11) // Left(Too large)
This is the essentially the same as the Java example you referenced. The A constructor is private, so the class can only be instantiated via the factory method.
Related
This question already has answers here:
How to create an instance of type T at runtime with TypeTags
(4 answers)
Closed 2 years ago.
In Scala, even if the solution is not elegant, is it possible to instantiate/create a new object of a generic type T? Is it possible to achieve this using reflection?
For example, I am interested in something like the following:
case class Person(name: String, age: Int)
Let's say I wanted to do the following to create an object of type Person:
def createObject[T](fieldValues: Seq[Any]): T = {
... T(fieldValues)
}
val person = createObject[Person](Seq("Bob", 20))
No, it is not possible. T is a parameter. You do not know anything about it. You do not even know if it can be instantiated at all. It might be a trait or an abstract class or a singleton type or a compound type.
That is the whole point of parametric polymorphism. To write code that does not need to know anything about the types it is dealing with.
Just as an example, it is perfectly legal to call your method like this:
val goodLuck = createObject[Nothing](Seq(1, 2))
Well, Nothing is literally defined as "the type which cannot have an instance". How are you going to instantiate this?
Technically speaking it's possible using reflection. You could for example catch runtime class of type T using ClassTag then find proper constructor and create instance:
def createObject[T](fieldValues: Seq[Any])(implicit ct: ClassTag[T]): Option[T] = {
//we lookup for matching constructor using arguments count, you might also consider checking types
ct.runtimeClass.getConstructors.find(_.getParameterCount == fieldValues.size)
.flatMap {constructor =>
Try(constructor.newInstance(fieldValues: _*).asInstanceOf[T]).toOption
}
}
createObject[Person](Seq("Bob", 20)) //Some(Person("Bob", 20))
createObject[Person](Seq(20, 10)) //None
In case there's no constructor matching parameters, that function fails returning None.
It should work, but it'd be best if you can avoid this approach because you lose all type safety.
This question already has answers here:
Scalaz pipe operator connected with a list method
(2 answers)
Closed 4 years ago.
I find myself writing Scala programs more often recently.
I like to program in a style that often uses long method chains, but sometimes the transformation you want to apply is not a method of the object you want to transform. So I find myself defining:
class Better[T] (t: T){
def xform[U](func: T => U) = func(t)
}
implicit def improve[T](t: T) = new Better(t)
This allows my to write the chains I want, such as
val content = s3.getObject(bucket, key)
.getObjectContent
.xform(Source.fromInputStream)
.mkString
.toInt
Is there any similar facility already in the standard library? If so, how should I have discovered it without resorting to StackOverflow?
It's not the standard library, but it might be "standard enough": with Cats, you should be able to write something like
val content =
s3
.getObject(bucket, key)
.getObjectContent
.pure[Id].map(Source.fromInputStream)
.mkString
.toInt
where pure[Id] wraps the input value into the do-nothing Id monad, and then passes it as argument to Source.fromInputStream.
EDIT: This does not seem to work reliably. If the object already has a method map, then this method is called instead of Id.map.
Smaller example (just to demonstrate the necessary imports):
import cats.Id
import cats.syntax.applicative._
import cats.syntax.functor._
object Main {
def square(x: Int) = x * x
def main(args: Array[String]): Unit = {
println(42.pure[Id].map(square))
}
}
However, writing either
val content =
Source
.fromInputStream(
s3
.getObject(bucket, key)
.getObjectContent
)
.mkString
.toInt
or
val content =
Source
.fromInputStream(s3.getObject(bucket, key).getObjectContent)
.mkString
.toInt
does not require any extra dependencies, and frees you both from the burden of defining otherwise useless case classes, and also from the burden of reindenting your code every time you rename either content or s3.
It also shows how the expressions are actually nested, and what depends on what - there is a reason why the vast majority of mainstream programming languages of the past 50 years have a call-stack.
This question already has answers here:
What is the eta expansion in Scala?
(2 answers)
Closed 4 years ago.
New to Scala, have searched far and wide for clarification on some ScalaMock syntax. As per this guide, I keep seeing the following general testing pattern:
(myClass.myMethod _).expects()
What exactly is happening here? What function does the class/method/space/underscore serve? How does the compiler treat this?
The appended _ forces the conversion of a method into a function.
To understand why this is necessary, let's try to re-build a tiny piece of Scalamock, namely the expects method. The expects method seems to be invoked on methods of mocked objects. But methods / functions do not have an expects method to begin with. Therefore, we have to use the "pimp my library"-pattern to attach the method expects to functions. We could do something like this:
implicit class ExpectsOp[A, B](f: A => B) {
def expects(a: A): Unit = println("it compiles, ship it...")
}
Now let's define a class Bar with method baz:
class Bar {
def baz(i: Int): Int = i * i
}
and also an instance of Bar:
val bar = new Bar
Let's see what happens if you try to invoke expects on bar.baz:
(bar.baz).expects(42)
error: missing argument list for method baz in class Bar
Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing baz _ or baz(_) instead of baz.
So, it doesn't work without explicit conversion into a function, and we have to enforce this conversion by appending an _:
(bar.baz _).expects(42) // prints: "it compiles, ship it..."
This question already has an answer here:
Typeclasses and inheritance in scalaz
(1 answer)
Closed 7 years ago.
I was playing with scalaz and thought I could extend Enum type class for something to make myself understand scalaz better. So I wrote this:
sealed abstract trait Counter
case object First extends Counter
case object Second extends Counter
case object Third extends Counter
implicit val enumCounter: Enum[Counter] = new Enum[Counter] {
override def succ(a: Counter): Counter = a match {
case First => Second
case Second => Third
case Third => First
}
override def pred(a: Counter): Counter = a match {
case First => Third
case Second => First
case Third => Second
}
override def order(x: Counter, y: Counter): Ordering = {
val map = Map[Counter, Int](First -> 0, Second -> 1, Third -> 2)
implicitly[Order[Int]].order(map(x), map(y))
}
}
println(First |=> Third)
println(First.succ)
But it turns out that it doesn't work as I hoped it will. First does not have succ nor |=>, because I've created Enum[Counter] but not Enum[First]. If I write First.asInstanceOf[Counter].succ it starts to resolve. Which is now obvious to me. But how can I implement Enum typeclass then in a simple way? I do not want to declare separate implicit values for each of Enum[First], Enum[Second]....
There are two possible solutions I am thinking of:
1) Make scala resolve Enum[First] as Enum[Counter]. But I cannot seem to understand how this can be possible as Enum can be only nonvariant
2) Maybe there is a solution in scalaz?
Otherwise Enum typeclass starts to be quite limited, as it does not supports Enum which sounds very weird.
I am actually not sure how much this question belongs to scalaz, it probably depends on whether the solution is (1) or (2). If the solution is (1) - this question is pure scala.
I rethought the question and rephrased it a lot - and received an answer, please see this: Typeclasses and inheritance in scalaz
Is it possible to validate arguments in an overloaded constructor before calling the default one? E.g. assume that my class has a default constructor
Clazz(foo: String, bar: String)
And I would like to provide another constructor
def this(fooBar: String) {
//validate if fooBar is of form FOO-BAR, if not, throw some custom exception, else invoke
this(fooBar.split("-")(0), fooBar.split("-")(1))
}
Is it possible to somehow perform the validation?
Auxiliary constructors in Scala have to invoke another constructor as the first thing they do, see the Scala Language Reference, Section 5.3.1, p. 74 or Scala constructor overload? So, validation of arguments in the way suggested is not possible.
See also Why can auxiliary constructors in Scala only consist of a single call to another constructor? The book "Programming in Scala" by Odersky, Spoon, and Venners sates the following on this topic (Section 6.7, p. 147):
If you’re familiar with Java, you may wonder why Scala’s rules for
constructors are a bit more restrictive than Java’s. In Java, a
constructor must either invoke another constructor of the same class,
or directly invoke a constructor of the superclass, as its first
action. In a Scala class, only the primary constructor can invoke a
superclass constructor. The increased restriction in Scala is really a
design trade-off that needed to be paid in exchange for the greater
conciseness and simplicity of Scala’s constructors compared to Java’s.
Superclasses and the details of how constructor invocation and
inheritance interact will be explained in Chapter 10.
As a solution to your question, you might want to consider factory objects, see, e.g., http://fupeg.blogspot.in/2008/11/scala-constructors.html or http://alvinalexander.com/scala/factory-pattern-in-scala-design-patterns This would lead to something like the following (with a more sophisticated validation, probably):
case class Clazz(foo : String, bar : String)
case class FooBarException(msg: String) extends RuntimeException(msg)
object Clazz {
def apply(fooBar : String) : Clazz =
if (fooBar.count(_ == '-') == 1)
new Clazz(fooBar.split("-")(0), fooBar.split("-")(1))
else
throw new FooBarException("not valid: " + fooBar)
}
object Test extends App {
val c1 = Clazz("foo", "bar")
println(c1)
val c2 = Clazz("foo-bar")
println(c2)
try {
val c3 = Clazz("will throw error")
} catch {
case FooBarException(msg) => println(msg)
}
}