Companion object constructor visibility

View: New views
6 Messages — Rating Filter:   Alert me  

Companion object constructor visibility

by Viktor Klang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Greetings Scalars,

Topic: Constructor visibility and companion object constructors

Given the following code, the 2.7.5 Scalac compiler tosses me a fine error: "constructor Name cannot be accessed in object ValueTypes1"

    object ValueTypes1
    {
        trait TypeDef[F,T <: TypeDef[F,T]]
        {
            val value : F
            override def toString = super.getClass.getSimpleName + "(" + value + ")"
        }

        abstract class TypeDefFactory[F,T <: TypeDef[F,T]](ctor : (F) => T, p : (F) => boolean)
        {
            def apply(f : F) : Option[T] = if(validate(f)) Some(ctor(f)) else None
            def unapply(t : T) : Option[F] = if(t eq null) None else Some(t.value)

            def validate(f : F) : boolean = p(f)
        }

        class Name private (val value : String) extends TypeDef[String,Name]

        object Name extends TypeDefFactory[String,Name]( new Name(_), !_.isEmpty ) // new Name(_) causes the error
    }


Now, since I cannot write: Some( new T(f) )  in the apply-method of the TypeDefFactory, I see no other solution than modify TypeDefFactory so the inheriting class/object has to define a "create" method as so:

        abstract class TypeDefFactory[F,T <: TypeDef[F,T]](p : (F) => boolean) // removed ctor : (F) => T,
        {
            def apply(f : F) : Option[T] = if(validate(f)) Some(ctor(f)) else None
            def unapply(t : T) : Option[F] = if(t eq null) None else Some(t.value)

            def validate(f : F) : boolean = p(f)
            def create(f : F) : T
        }

        class Name private (val value : String) extends TypeDef[String,Name]

        object Name extends TypeDefFactory[String,Name]( !_.isEmpty ) // removed new Name(_)
        {
           def create(s : String) = new Name(s)
        }

    }

However, this adds boilerplate, which I am very unfond of, so my question is:

Why is "new Name(_)" in the ValueTypes1 scope instead of the Name scope? Because the super-constructor call (TypeDefFactory((F) => T,(F) => boolean ) should _definately_ be in the scope of the inheriting class.
Or am I missing something?

Best regards,
--
Viktor Klang
Scala Loudmouth

Re: Companion object constructor visibility

by Paul Phillips-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Jul 05, 2009 at 01:11:03PM +0200, Viktor Klang wrote:
> Given the following code, the 2.7.5 Scalac compiler tosses me a fine
> error: "constructor Name cannot be accessed in object ValueTypes1"

Companion objects don't really work if they're not top level.

> Now, since I cannot write: *Some( new T(f) ) *in the apply-method of
> the TypeDefFactory, I see no other solution than modify TypeDefFactory
> so the inheriting class/object has to define a "create" method as so:

class Name private[ValueTypes1] (val value : String)

> Why is "new Name(_)" in the ValueTypes1 scope instead of the Name
> scope?

This is not a scoping issue, but a limitation of access modifiers.
"new Name(_)" means what you want it to mean, it's just locked out.

--
Paul Phillips      | Beware of bugs in the above code; I have only
Everyman           | proved it correct, not tried it.
Empiricist         |     -- Knuth
i'll ship a pulp   |----------* http://www.improving.org/paulp/ *----------

Re: Companion object constructor visibility

by Viktor Klang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Sun, Jul 5, 2009 at 2:58 PM, Paul Phillips <paulp@...> wrote:
On Sun, Jul 05, 2009 at 01:11:03PM +0200, Viktor Klang wrote:
> Given the following code, the 2.7.5 Scalac compiler tosses me a fine
> error: "constructor Name cannot be accessed in object ValueTypes1"

Companion objects don't really work if they're not top level.

Ah, ok, I just put it in an object to scope it...
 


> Now, since I cannot write: *Some( new T(f) ) *in the apply-method of
> the TypeDefFactory, I see no other solution than modify TypeDefFactory
> so the inheriting class/object has to define a "create" method as so:

class Name private[ValueTypes1] (val value : String)

> Why is "new Name(_)" in the ValueTypes1 scope instead of the Name
> scope?

This is not a scoping issue, but a limitation of access modifiers.
"new Name(_)" means what you want it to mean, it's just locked out.

I'm not sure I follow _why_.
Given the following code below:

     class Name private (val value : String) extends TypeDef[String,Name]
     object Name extends TypeDefFactory[String,Name]( new Name(_), !_.isEmpty ) // new Name(_) causes the error
 
The call to TypeDefFactory's constructor with signature ((String) => Name, (String) => boolean) should occur within the Name scope, and since Name is a companion object of class Name, the constructor call should be visible to the companion object, which it is, outside the companion objects constructor.

object Name { def create = new Name("foo") } //This is valid..

So I fail to see why the class Name construtor is illegal in the constructor, but not in the companion body.

Could you direct me to the appropriate part of the SLS that explains this?



--
Paul Phillips      | Beware of bugs in the above code; I have only
Everyman           | proved it correct, not tried it.
Empiricist         |     -- Knuth
i'll ship a pulp   |----------* http://www.improving.org/paulp/ *----------



--
Viktor Klang
Scala Loudmouth

Re: Companion object constructor visibility

by Paul Phillips-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sorry, you might be looking at a variation of this:

  http://lampsvn.epfl.ch/trac/scala/ticket/1798

I'm not remembering the details of how supercalls are lifted, but it's
plausible to me that it's hitting the same problem.

--
Paul Phillips      | Before a man speaks it is always safe to assume
Vivid              | that he is a fool.  After he speaks, it is seldom
Empiricist         | necessary to assume it.
i'll ship a pulp   |     -- H. L. Mencken

Re: Companion object constructor visibility

by Viktor Klang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'll file it as a bug tomorrow, and see what happens :)

On Sun, Jul 5, 2009 at 4:06 PM, Paul Phillips <paulp@...> wrote:
Sorry, you might be looking at a variation of this:

 http://lampsvn.epfl.ch/trac/scala/ticket/1798

I'm not remembering the details of how supercalls are lifted, but it's
plausible to me that it's hitting the same problem.

--
Paul Phillips      | Before a man speaks it is always safe to assume
Vivid              | that he is a fool.  After he speaks, it is seldom
Empiricist         | necessary to assume it.
i'll ship a pulp   |     -- H. L. Mencken



--
Viktor Klang
Scala Loudmouth

Re: Companion object constructor visibility

by Viktor Klang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Filed: https://lampsvn.epfl.ch/trac/scala/ticket/2127

On Sun, Jul 5, 2009 at 11:28 PM, Viktor Klang <viktor.klang@...> wrote:
I'll file it as a bug tomorrow, and see what happens :)


On Sun, Jul 5, 2009 at 4:06 PM, Paul Phillips <paulp@...> wrote:
Sorry, you might be looking at a variation of this:

 http://lampsvn.epfl.ch/trac/scala/ticket/1798

I'm not remembering the details of how supercalls are lifted, but it's
plausible to me that it's hitting the same problem.

--
Paul Phillips      | Before a man speaks it is always safe to assume
Vivid              | that he is a fool.  After he speaks, it is seldom
Empiricist         | necessary to assume it.
i'll ship a pulp   |     -- H. L. Mencken



--
Viktor Klang
Scala Loudmouth



--
Viktor Klang
Scala Loudmouth