|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
trait X extends Y vs trait X {this: Y=> }Hi everyone,
I am a little confused by the two ways to indicate that a trait must form part of a given concrete class: extension versus self-types, as shown in the subject. I have noticed that there are some differences in behaviour between the two. Can anyone help explain the difference between them, and what situations benefit from using one or the other? Thanks for you time, Ken |
|
|
Re: trait X extends Y vs trait X {this: Y=> }The self type only enforces that you are *mixed-into* a particular type. A trait that extends another could possibly be used standalone.
I would reserve self-types for things that truly are just mixins, and a "class instantiation concern". This means the following: trait X extends Y // X *is a* Y trait X { self : Y => ... } // X is a helper that can be used with a Y. I would tend to prefer this over aspects for specific kinds of mixin functionality. An example from EJB (yes... I know) trait BaseDataAccessEJB { def tx : UserTransaction def entityManager : EntityManager } trait TransactionHelper { self : BaseDataAccessEJB => //This is a toy implementation, in reality there are far more concerns to worry about in this method def transactional(f : => A) : A = { tx.start() try { f } finally { tx.commit() } } } Then when creating a new EJB I can do class MyEJB extends BaseDataAccessEJB with TransactionHelper I hope that helps, - Josh On Fri, Nov 6, 2009 at 7:35 PM, Ken Scambler <ken.scambler@...> wrote:
|
|
|
Re: trait X extends Y vs trait X {this: Y=> }On Fri, Nov 6, 2009 at 4:47 PM, Josh Suereth <joshua.suereth@...> wrote:
> The self type only enforces that you are *mixed-into* a particular type. A > trait that extends another could possibly be used standalone. > > I would reserve self-types for things that truly are just mixins, and a > "class instantiation concern". This means the following: It can also be used to influence the linearization order of the traits. Maybe one should be careful in using this feature, but notice the difference in: scala> trait Foo { def foo = println("Foo") } defined trait Foo scala> trait Bar extends Foo { override def foo { println("Bar"); super.foo } } defined trait Bar scala> trait Baz extends Foo { this : Bar => override def foo { println("Baz"); super.foo; } } defined trait Baz scala> val a = new Bar with Baz; a: java.lang.Object with Bar with Baz = $anon$1@ee13d0 scala> a.foo Baz Bar Foo scala> val b = new Baz with Bar; b: java.lang.Object with Baz with Bar = $anon$1@4deff4f scala> b.foo Bar Baz Foo <<<<<Versus>>>> scala> trait Foo2 { def foo = println("foo"); } defined trait Foo2 scala> trait Bar2 extends Foo2 { override def foo { println("bar"); super.foo } } defined trait Bar2 scala> trait Baz2 extends Bar2 { override def foo { println("baz"); super.foo } } defined trait Baz2 scala> new Bar2 with Baz2 foo baz bar foo scala> new Baz2 with Bar2 foo baz bar foo -- David > > trait X extends Y // X *is a* Y > > trait X { self : Y => ... } // X is a helper that can be used with a Y. > I would tend to prefer this over aspects for specific kinds of mixin > functionality. > > An example from EJB (yes... I know) > > trait BaseDataAccessEJB { > def tx : UserTransaction > def entityManager : EntityManager > } > > > trait TransactionHelper { self : BaseDataAccessEJB => > > //This is a toy implementation, in reality there are far more concerns to > worry about in this method > def transactional(f : => A) : A = { > tx.start() > try { > f > } finally { > tx.commit() > } > } > } > > > Then when creating a new EJB I can do class MyEJB extends > BaseDataAccessEJB with TransactionHelper > > > > I hope that helps, > > - Josh > > On Fri, Nov 6, 2009 at 7:35 PM, Ken Scambler <ken.scambler@...> wrote: >> >> Hi everyone, >> I am a little confused by the two ways to indicate that a trait must form >> part of a given concrete class: extension versus self-types, as shown in >> the >> subject. I have noticed that there are some differences in behaviour >> between the two. >> >> Can anyone help explain the difference between them, and what situations >> benefit from using one or the other? >> >> Thanks for you time, >> Ken >> -- >> View this message in context: >> http://old.nabble.com/trait-X-extends-Y-vs-trait-X-%7Bthis%3A-Y%3D%3E-%7D-tp26233138p26233138.html >> Sent from the Scala - User mailing list archive at Nabble.com. >> > > |
|
|
Re: trait X extends Y vs trait X {this: Y=> }Well, let me put it another way. If you say X extends Y, then you are saying X has Y's implementation. If you say self: Y =>, you are saying the class you are mixed into must implement interface Y.
In the first case, the class mixing X in can't choose a descendant of Y, in the second it can.
On Fri, Nov 6, 2009 at 10:35 PM, Ken Scambler <ken.scambler@...> wrote:
-- Daniel C. Sobral Veni, vidi, veterni. |
|
|
Re: trait X extends Y vs trait X {this: Y=> }On Sat, Nov 7, 2009 at 7:33 PM, Daniel Sobral <dcsobral@...> wrote:
> Well, let me put it another way. If you say X extends Y, then you are saying > X has Y's implementation. If you say self: Y =>, you are saying the class > you are mixed into must implement interface Y. > In the first case, the class mixing X in can't choose a descendant of Y, in > the second it can. It can in both cases, scala> class A defined class A scala> class B extends A defined class B scala> trait C extends A defined trait C scala> class D extends B with C defined class D Cheers, Miles -- Miles Sabin tel: +44 (0)7813 944 528 skype: milessabin http://www.chuusai.com/ http://twitter.com/milessabin |
|
|
Re: trait X extends Y vs trait X {this: Y=> }Hmm. Now I realize that both " this: A =>" and "self: A =>" are there.
Strange redundancy (assuming they are equivalent). Anyone knows why this is so? 2009/11/7 Daniel Sobral <dcsobral@...>: > Well, let me put it another way. If you say X extends Y, then you are saying > X has Y's implementation. If you say self: Y =>, you are saying the class > you are mixed into must implement interface Y. > In the first case, the class mixing X in can't choose a descendant of Y, in > the second it can. > > On Fri, Nov 6, 2009 at 10:35 PM, Ken Scambler <ken.scambler@...> > wrote: >> >> Hi everyone, >> I am a little confused by the two ways to indicate that a trait must form >> part of a given concrete class: extension versus self-types, as shown in >> the >> subject. I have noticed that there are some differences in behaviour >> between the two. >> >> Can anyone help explain the difference between them, and what situations >> benefit from using one or the other? >> >> Thanks for you time, >> Ken >> -- >> View this message in context: >> http://old.nabble.com/trait-X-extends-Y-vs-trait-X-%7Bthis%3A-Y%3D%3E-%7D-tp26233138p26233138.html >> Sent from the Scala - User mailing list archive at Nabble.com. >> > > > > -- > Daniel C. Sobral > > Veni, vidi, veterni. > |
|
|
Re: trait X extends Y vs trait X {this: Y=> }Dimitris Andreou a écrit :
> Hmm. Now I realize that both " this: A =>" and "self: A =>" are there. > Strange redundancy (assuming they are equivalent). Anyone knows why > this is so? It's just a binding name. You can use whatever is meaningful for your use case, and "self" or "this" are conventional name. But you can rebind "this" to something else without the type annotation, for example to make reference to that "this" in inner classes. Ex: class Outer(name:String) { outer => class Inner { def whoOwnsMe() { println( outer.name ) } } } -- Francois Armand http://fanf42.blogspot.com |
| Free embeddable forum powered by Nabble | Forum Help |