abstract override weirdness

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

abstract override weirdness

Nils Kilden-Pedersen
Any way to get this to work?

trait SimpleTrait {
  def convert(number: String): Int
}

trait OverridingTrait extends SimpleTrait {
  abstract override def convert(number: String) = try {
    super.convert(number)
  } catch {
    case e: IllegalArgumentException => throw new RuntimeException("Not a number: " + number)
  }
}

class Converter extends SimpleTrait with OverridingTrait {
  def convert(number: String) = Integer.parseInt(number)
}

Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Jan Lohre
Hi Nils,

it is always helpful to provide information on what is not working and what you want to achieve (in order to get alternative proposals on how to achieve it).

Kind regards,
Jan

2009/8/2 Nils Kilden-Pedersen <[hidden email]>
Any way to get this to work?

trait SimpleTrait {
  def convert(number: String): Int
}

trait OverridingTrait extends SimpleTrait {
  abstract override def convert(number: String) = try {
    super.convert(number)
  } catch {
    case e: IllegalArgumentException => throw new RuntimeException("Not a number: " + number)
  }
}

class Converter extends SimpleTrait with OverridingTrait {
  def convert(number: String) = Integer.parseInt(number)
}


Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Jan Lohre
Having said this I had a look at your example. Be cautious with what I say below because I am missing pratical experience with more then play code in scala.

You are calling the super implementation of convert without actually inheriting a concrete implementation (I guess thats why the abstract modifier is neccessary)
That means there has to be some super-class/trait for your OverridingTrait so that the super call makes sense. You could introduce a ConcreteTrait to give an implementation and do it as in the following:

trait SimpleTrait {
  def convert(number: String): Int
}

trait OverridingTrait extends SimpleTrait {
  abstract override def convert(number: String) = try {
    super.convert(number)
  } catch {
    case e: IllegalArgumentException => throw new RuntimeException("Not a number: " + number)
  }
}

trait ConcreteTrait extends SimpleTrait {
  override def convert(number: String) = Integer.parseInt(number)
}

class Converter extends SimpleTrait with ConcreteTrait with OverridingTrait {
}

object Main {
  def main(args : Array[String]) : Unit = {
    val c = new Converter
    Console.println(c.convert("4a"))
  }
}

As trait linearization will take place from right to left the super call in OverridingTrait will call the concrete implementation in ConcreteTrait.

As I said this is without much practical experience with complex trait/class hierarchies.

Kind regards,
Jan

2009/8/2 Jan Lohre <[hidden email]>
Hi Nils,

it is always helpful to provide information on what is not working and what you want to achieve (in order to get alternative proposals on how to achieve it).

Kind regards,
Jan

2009/8/2 Nils Kilden-Pedersen <[hidden email]>

Any way to get this to work?

trait SimpleTrait {
  def convert(number: String): Int
}

trait OverridingTrait extends SimpleTrait {
  abstract override def convert(number: String) = try {
    super.convert(number)
  } catch {
    case e: IllegalArgumentException => throw new RuntimeException("Not a number: " + number)
  }
}

class Converter extends SimpleTrait with OverridingTrait {
  def convert(number: String) = Integer.parseInt(number)
}



Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Nils Kilden-Pedersen
On Sun, Aug 2, 2009 at 6:34 AM, Jan Lohre <[hidden email]> wrote:
You are calling the super implementation of convert without actually inheriting a concrete implementation (I guess thats why the abstract modifier is neccessary)
Yes.

That means there has to be some super-class/trait for your OverridingTrait so that the super call makes sense.
Yes, that's what the Converter class is.
 
You could introduce a ConcreteTrait to give an implementation and do it as in the following:
 
trait ConcreteTrait extends SimpleTrait {
  override def convert(number: String) = Integer.parseInt(number)
}

class Converter extends SimpleTrait with ConcreteTrait with OverridingTrait {
}

Ok, for some reason that seems to work. Any idea why I have to have the implementation in a trait instead of a class? A bug?
BTW, I' trying this in Eclipse with 2.7.5 and am getting this error:
error overriding method convert in trait OverridingTrait of type (String)Int;
 method convert needs `override' modifier

Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Randall R Schulz-2
On Sunday August 2 2009, Nils Kilden-Pedersen wrote:
> ...
>
> Ok, for some reason that seems to work. Any idea why I have to have
> the implementation in a trait instead of a class? A bug?
> BTW, I' trying this in Eclipse with 2.7.5 and am getting this error:
> error overriding method convert in trait OverridingTrait of type
> (String)Int;
>  method convert needs `override' modifier

If you're inhereting a member with an implementation (not just a
declaration), then you have to explicitly state your intent to override
that inherited method (or val or var) by supplying the "override"
keyword.


Randall Schulz
Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Nils Kilden-Pedersen
On Sun, Aug 2, 2009 at 10:04 AM, Randall R Schulz <[hidden email]> wrote:
If you're inhereting a member with an implementation (not just a
declaration), then you have to explicitly state your intent to override
that inherited method (or val or var) by supplying the "override"
keyword.

After I sent it, I realized that someone was going to make that comment. I have of course tried that. And it leads to this error:

error overriding method convert in trait OverridingTrait of type (String)Int;
 method convert needs `abstract override' modifiers

And the next error is as expected:

`abstract override' modifier only allowed for members of traits

Ahh, yes, not very helpful.

Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Jan Lohre
In reply to this post by Nils Kilden-Pedersen


2009/8/2 Nils Kilden-Pedersen <[hidden email]>
On Sun, Aug 2, 2009 at 6:34 AM, Jan Lohre <[hidden email]> wrote:
You are calling the super implementation of convert without actually inheriting a concrete implementation (I guess thats why the abstract modifier is neccessary)
Yes.

That means there has to be some super-class/trait for your OverridingTrait so that the super call makes sense.
Yes, that's what the Converter class is.

No, the Converter class is a subclass/implementation of the traits, not a super-class.
 

 
You could introduce a ConcreteTrait to give an implementation and do it as in the following:
 
trait ConcreteTrait extends SimpleTrait {

  override def convert(number: String) = Integer.parseInt(number)
}

class Converter extends SimpleTrait with ConcreteTrait with OverridingTrait {
}

Ok, for some reason that seems to work. Any idea why I have to have the implementation in a trait instead of a class? A bug?
BTW, I' trying this in Eclipse with 2.7.5 and am getting this error:
error overriding method convert in trait OverridingTrait of type (String)Int;
 method convert needs `override' modifier


Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Nils Kilden-Pedersen
On Sun, Aug 2, 2009 at 2:56 PM, Jan Lohre <[hidden email]> wrote:


2009/8/2 Nils Kilden-Pedersen <[hidden email]>
On Sun, Aug 2, 2009 at 6:34 AM, Jan Lohre <[hidden email]> wrote:

You are calling the super implementation of convert without actually inheriting a concrete implementation (I guess thats why the abstract modifier is neccessary)
Yes.

That means there has to be some super-class/trait for your OverridingTrait so that the super call makes sense.
Yes, that's what the Converter class is.

No, the Converter class is a subclass/implementation of the traits, not a super-class.

But why does this work then?:

class Converter extends SimpleTrait {
  def convert(n: String) = Integer.parseInt(n)
}

val c = new Converter with OverridingTrait

So I can use OverridingTrait in an anonymous type definition, but not in a named one. That's gotta be a bug, unless I misunderstand something.
Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Jan Lohre
I will basically let this question for others to answer.

My guess would be that in this case you create kind of an anonymous class (Converter with OverridingTrait) that extends Converter.

But beside that this is only a guess - maybe you are right and it is a bug - and I am not sure I dived deep enough into scala yet to give a qualified anwer; why do you want such a construct in the first place?

2009/8/2 Nils Kilden-Pedersen <[hidden email]>
On Sun, Aug 2, 2009 at 2:56 PM, Jan Lohre <[hidden email]> wrote:


2009/8/2 Nils Kilden-Pedersen <[hidden email]>
On Sun, Aug 2, 2009 at 6:34 AM, Jan Lohre <[hidden email]> wrote:

You are calling the super implementation of convert without actually inheriting a concrete implementation (I guess thats why the abstract modifier is neccessary)
Yes.

That means there has to be some super-class/trait for your OverridingTrait so that the super call makes sense.
Yes, that's what the Converter class is.

No, the Converter class is a subclass/implementation of the traits, not a super-class.

But why does this work then?:

class Converter extends SimpleTrait {
  def convert(n: String) = Integer.parseInt(n)
}

val c = new Converter with OverridingTrait

So I can use OverridingTrait in an anonymous type definition, but not in a named one. That's gotta be a bug, unless I misunderstand something.

Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Naftoli Gugenheim
In reply to this post by Nils Kilden-Pedersen
When you mix in traits they override each other in the order you specify them.

-------------------------------------
Jan Lohre<[hidden email]> wrote:

I will basically let this question for others to answer.

My guess would be that in this case you create kind of an anonymous class
(Converter with OverridingTrait) that extends Converter.

But beside that this is only a guess - maybe you are right and it is a bug -
and I am not sure I dived deep enough into scala yet to give a qualified
anwer; why do you want such a construct in the first place?

2009/8/2 Nils Kilden-Pedersen <[hidden email]>

> On Sun, Aug 2, 2009 at 2:56 PM, Jan Lohre <[hidden email]>wrote:
>
>>
>>
>> 2009/8/2 Nils Kilden-Pedersen <[hidden email]>
>>
>>> On Sun, Aug 2, 2009 at 6:34 AM, Jan Lohre <[hidden email]>wrote:
>>>
>>>> You are calling the super implementation of convert without actually
>>>> inheriting a concrete implementation (I guess thats why the abstract
>>>> modifier is neccessary)
>>>
>>> Yes.
>>>
>>>  That means there has to be some super-class/trait for your
>>>> OverridingTrait so that the super call makes sense.
>>>
>>> Yes, that's what the Converter class is.
>>>
>>
>> No, the Converter class is a subclass/implementation of the traits, not a
>> super-class.
>>
>
> But why does this work then?:
>
> class Converter extends SimpleTrait {
>   def convert(n: String) = Integer.parseInt(n)
> }
>
> val c = new Converter with OverridingTrait
>
> So I can use OverridingTrait in an anonymous type definition, but not in a
> named one. That's gotta be a bug, unless I misunderstand something.
>
Reply | Threaded
Open this post in threaded view
|

Re: abstract override weirdness

Nils Kilden-Pedersen
In reply to this post by Jan Lohre
On Sun, Aug 2, 2009 at 4:48 PM, Jan Lohre <[hidden email]> wrote:
why do you want such a construct in the first place?

Good question. Maybe I don't. I guess I could just add that functionality in the Converter's implementation. It would just look cleaner the other way, with better separation of concerns. But maybe that's why it's not a bug. Because I don't really need it.