This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Re: Is Dynamic Object Decoration Possible

3 replies
Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
This is generally what implicit conversions are used for.

trait MyTrait[T] {
  def myObject : T
  def myMethod = {
    //...
  }
}

implicit def decorate[T](o : T) : MyTrait[T] = new MyTrait[T] {
  override def myObject = o
}

Then, whenever you have an instance of whatever the decorated type is, you can do

val o = new Foo()

o.myMethod

Kris

On Fri, Jan 16, 2009 at 10:30 AM, Bastian, Mark <mbastia [at] sandia [dot] gov> wrote:
Scala gives you the powerful ability to create object factories that decorate the primary object wth a trait like so with no explicit class definition:   def objectWithTrait = new MyObject with MyTrait   Is it possible to dynamically decorate an object, like so:   def decorate(o : Object) : Object = o with MyTrait   I suppose you could make a cloning factory that does something like this:   def cloneAndDecorate(o : MyObject) {   //foo and bar are copy constructor fields   new o(o.foo, o.bar) with MyTrait }   This might be adequate in some situations, but it might be nice to be able to dynamically add the trait. Can it be done?   Thanks, Mark  


John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Is Dynamic Object Decoration Possible
The problem with the implicit wrapper sollution is that the new type is "MyTrait[T]" not, T with MyTrait. Meaning that the wrapper doesn't have the same methods as T.
One sollution that might work right now is to use a DynamicProxy[1] to wrap the object in and cast it to T with MyTrait.
If I'm not mistaken Scala generates Interface instances for most things, and as long as you can pass those instances to the proxy factory you should be fine.
BR, John

[1] http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html
On Fri, Jan 16, 2009 at 7:14 PM, Kris Nuttycombe <kris [dot] nuttycombe [at] gmail [dot] com> wrote:
This is generally what implicit conversions are used for.

trait MyTrait[T] {
  def myObject : T
  def myMethod = {
    //...
  }
}

implicit def decorate[T](o : T) : MyTrait[T] = new MyTrait[T] {
  override def myObject = o
}

Then, whenever you have an instance of whatever the decorated type is, you can do

val o = new Foo()

o.myMethod

Kris

On Fri, Jan 16, 2009 at 10:30 AM, Bastian, Mark <mbastia [at] sandia [dot] gov> wrote:
Scala gives you the powerful ability to create object factories that decorate the primary object wth a trait like so with no explicit class definition:   def objectWithTrait = new MyObject with MyTrait   Is it possible to dynamically decorate an object, like so:   def decorate(o : Object) : Object = o with MyTrait   I suppose you could make a cloning factory that does something like this:   def cloneAndDecorate(o : MyObject) {   //foo and bar are copy constructor fields   new o(o.foo, o.bar) with MyTrait }   This might be adequate in some situations, but it might be nice to be able to dynamically add the trait. Can it be done?   Thanks, Mark  



Kris Nuttycombe
Joined: 2009-01-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Is Dynamic Object Decoration Possible
Hmm. Can you elaborate a little? In any of the code where that implicit definition is in scope, you can call the methods of either T or MyTrait on any instance of T.

Or do you want to pass the resulting object out of that scope and be able to reflect upon all of its types in the receiving scope? I don't think there's a way to do that.

Kris

On Fri, Jan 16, 2009 at 2:38 PM, John Nilsson <john [at] milsson [dot] nu> wrote:
The problem with the implicit wrapper sollution is that the new type is "MyTrait[T]" not, T with MyTrait. Meaning that the wrapper doesn't have the same methods as T.
One sollution that might work right now is to use a DynamicProxy[1] to wrap the object in and cast it to T with MyTrait.
If I'm not mistaken Scala generates Interface instances for most things, and as long as you can pass those instances to the proxy factory you should be fine.
BR, John

[1] http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html
On Fri, Jan 16, 2009 at 7:14 PM, Kris Nuttycombe <kris [dot] nuttycombe [at] gmail [dot] com> wrote:
This is generally what implicit conversions are used for.

trait MyTrait[T] {
  def myObject : T
  def myMethod = {
    //...
  }
}

implicit def decorate[T](o : T) : MyTrait[T] = new MyTrait[T] {
  override def myObject = o
}

Then, whenever you have an instance of whatever the decorated type is, you can do

val o = new Foo()

o.myMethod

Kris

On Fri, Jan 16, 2009 at 10:30 AM, Bastian, Mark <mbastia [at] sandia [dot] gov> wrote:
Scala gives you the powerful ability to create object factories that decorate the primary object wth a trait like so with no explicit class definition:   def objectWithTrait = new MyObject with MyTrait   Is it possible to dynamically decorate an object, like so:   def decorate(o : Object) : Object = o with MyTrait   I suppose you could make a cloning factory that does something like this:   def cloneAndDecorate(o : MyObject) {   //foo and bar are copy constructor fields   new o(o.foo, o.bar) with MyTrait }   This might be adequate in some situations, but it might be nice to be able to dynamically add the trait. Can it be done?   Thanks, Mark  




John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Is Dynamic Object Decoration Possible
On Sat, Jan 17, 2009 at 2:45 AM, Kris Nuttycombe <kris [dot] nuttycombe [at] gmail [dot] com> wrote:
Hmm. Can you elaborate a little? In any of the code where that implicit definition is in scope, you can call the methods of either T or MyTrait on any instance of T.
You're right, didn't think of that. I don't think that works to well with overriding though.  
Or do you want to pass the resulting object out of that scope and be able to reflect upon all of its types in the receiving scope? I don't think there's a way to do that.
Using dynamix proxy it should be possible. The returned object is just a facade implementing all the interfaces passed to the proxy factory.
It was a while ago now, but I was trying this approach to be able to implement JOIN in my own SQL API. At the time I think I had some probles getting the instances of the interfaces needed to join structural types or something like that.
BR,John

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland