Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala analogue to "with object do begin ... end" (shortcutting method access)

Tags:

scala

In old rusty Pascal there were convenient construct to perform a sequence of actions on object or record:

with obj do
begin
  methodCall
  otherMethodCall
  ...
end

I'm trying to touch something similar in scala, but something missing in my head :)

Is it possible to achieve somehow such effect, as if obj was in current scope of passed closure and behaved as this:

{
  import obj._
  callObjMethod(x, y)
  objVal.doSomething()
  ...
}

But in customized syntax like:

doWith (obj) {
  callObjMethod(x, y)
  objVal.doSomething()
}

Intuitionally I feel that it's more no than yes but curiosity wants to know for sure.

like image 389
dmitry Avatar asked Mar 16 '13 14:03

dmitry


2 Answers

Do you mean like this?

val file = new java.io.File(".")

// later as long as file is in scope

{
  import file._
  println(isDirectory)
  println(getCanonicalPath())
}  

You can just use the import keyword to bring the methods of the object in scope.

like image 96
huynhjl Avatar answered Nov 01 '22 12:11

huynhjl


One possibility is the tap method:

def tap[A](obj: A)(actions: (A => _)*) = {
  actions.foreach { _(obj) }
  obj
}

tap(obj) (
  _.callObjMethod(x, y),
  _.objVal.doSomething()
)

or after using enrichment

implicit class RichAny[A](val obj: A) extends AnyVal {
  def tap(actions: (A => _)*) = {
    actions.foreach { _(obj) }
    obj
  }
}

obj.tap (
  _.callObjMethod(x, y),
  _.objVal.doSomething()
)

I think that with macros you should even be able to get your desired syntax (and avoid the overhead of creating the function objects), but I'll leave that to someone else.

like image 21
Alexey Romanov Avatar answered Nov 01 '22 13:11

Alexey Romanov