0

When working with existing libraries (can't edit constructors or companion objects) I often find that I need to call an init/setup procedure on an object and then return the object itself. I usually end up doing something like the following.

def createObject: MyObject = {
    val o = new MyObject
    o.init()
    o
}

This is IMHO not very elegant and I'm wondering if there's a better way of doing this, e.g., a setup-and-get function along the lines of:

def createObject: MyObject = {
    setupAndGet(new MyObject) { _.init(v) }
}

Are there any existing solutions to this in Scala (besides writing my own)?

Felix Glas
  • 15,065
  • 7
  • 53
  • 82
  • 1
    This isn't "functional-style." `o.store` acts by side-effect, so you are unlikely to find a built in way of doing what you want in Scala. – Karl Bielefeldt Oct 18 '17 at 12:03

3 Answers3

2

Well, each Scala case class come with a generated companion object that has an apply method that has this exact signature.

scala> case class Foo(s:String)
defined class Foo

scala> Foo.apply("hello")
res1: Foo = Foo(hello)

Note that the .apply() method is the default method call, you can simply write Foo("hello")

n1r3
  • 8,593
  • 3
  • 18
  • 19
1

The following may be what you want.

def applyAndGet(myObject: MyObject)(f: myObject.type => Unit): myObject.type = {
  f(myObject)
  myObject
}

But I will recommend calling a constructor like new MyObject(value).

蘇哲聖
  • 735
  • 9
  • 17
  • That would work, but I was looking for a possible "built-in" way of doing it without writing a custom function. – Felix Glas Oct 18 '17 at 11:09
1

Consider the following extension method (there is plenty of information about them, just google if you do not know what they are):

implicit class SetupExtension[T](private val t: T) extends AnyVal {
  def setup(code: T => Any): T = {
   code(t)
   t
  }
}
val s: MyObject = new MyObject.setup(_.setXProperty(???))

This method is quite usefull when you are working with some mutable api (from java libraries etc.). Other than that i would not recommend doing things this way.

L.Lampart
  • 755
  • 5
  • 10