- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Visibility of class parameters
Thu, 2009-12-03, 22:53
The following behavior was surprising to me and I'm wondering if it's
correct according to the language spec.
Welcome to Scala version 2.8.0.Beta1-RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).
scala> class C (x: Int)
defined class C
scala> new C(5)
res0: C = C@70f16568
scala> import res0.x
:6: error: x is not a member of res0
import res0.x
^
So far so good. x is only visible within C, so the error makes sense.
But now if I actually refer to x inside C:
scala> class C (x: Int) { def foo = x }
defined class C
scala> new C(5)
res1: C = C@530f243b
scala> import res1.x
import res1.x
scala> x
:8: error: value x cannot be accessed in C
x
^
I was able to import x, even though x cannot be accessed!
I understand that because foo refers to x, internally C must now have a
field for x. But it seems surprising to me that this change would
increase the visibility of x to other code.
Is this covered in the spec? Section 5.3, Class Definitions, covers
class parameters but it doesn't talk about what happens when a class
parameter is referred to in one of the class's methods. (I can't find a
section that does talk about that.)
Thu, 2009-12-03, 23:57
#2
Re: Visibility of class parameters
On Thu, Dec 3, 2009 at 10:54 PM, Seth Tisue wrote:
>
> The following behavior was surprising to me and I'm wondering if it's
> correct according to the language spec.
>
> Welcome to Scala version 2.8.0.Beta1-RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).
>
> scala> class C (x: Int)
> defined class C
>
> scala> new C(5)
> res0: C = C@70f16568
>
> scala> import res0.x
> :6: error: x is not a member of res0
> import res0.x
> ^
> So far so good. x is only visible within C, so the error makes sense.
> But now if I actually refer to x inside C:
>
> scala> class C (x: Int) { def foo = x }
> defined class C
>
> scala> new C(5)
> res1: C = C@530f243b
>
> scala> import res1.x
> import res1.x
>
> scala> x
> :8: error: value x cannot be accessed in C
> x
> ^
>
> I was able to import x, even though x cannot be accessed!
>
> I understand that because foo refers to x, internally C must now have a
> field for x. But it seems surprising to me that this change would
> increase the visibility of x to other code.
>
Imports are not subject to accessibility rules. In am import
statement, no attempt is made to check whether the imported value is
accessible -- in fact we could only do a rough approximation of
accessibility anyway, because the precise rules would depend on where
and how the identifier is then referred to later.
> Is this covered in the spec? Section 5.3, Class Definitions, covers
> class parameters but it doesn't talk about what happens when a class
> parameter is referred to in one of the class's methods. (I can't find a
> section that does talk about that.)
>
> --
It's covered in the chapter on imports. i cite:
Import selectors work in the same way for type and term members. For
instance, an import clause ~\lstinline@import $p$.{$x$ => $y\,$}@~
renames the term
name \lstinline@$p$.$x$@ to the term name $y$ and the type name
\lstinline@$p$.$x$@
to the type name $y$. At least one of these two names must
reference a member of $p$.
Note that nothing is said about whether the member needs to be accessible.
Cjeers
Fri, 2009-12-04, 00:27
#3
Re: Visibility of class parameters
On Thu, Dec 03, 2009 at 11:52:04PM +0100, martin odersky said
> > I understand that because foo refers to x, internally C must now have a
> > field for x. But it seems surprising to me that this change would
> > increase the visibility of x to other code.
> >
> Imports are not subject to accessibility rules. In am import
> statement, no attempt is made to check whether the imported value is
> accessible -- in fact we could only do a rough approximation of
> accessibility anyway, because the precise rules would depend on where
> and how the identifier is then referred to later.
I think the issue is different from accessibility. As the identifier x
is not a member (val, var or def) of class C there should not be
anything to import regardless of accessibility. In other words, while
the java signature for the class must contain a field for x, the scala
signature should not. I.e. fields with the paramaccessor flag should not
be selectable.
Fri, 2009-12-04, 02:27
#4
Re: Visibility of class parameters
>>>>> "martin" == martin odersky writes:
martin> Note that nothing is said about whether the member needs to be
martin> accessible.
I understand that visibility and accessibility are different, and that
something can be visible without being accessible.
In this case, though, why is x visible outside C? I think it should not
be, and I can find nothing in the spec to justify x's visibility
(though, am I missing something? it wouldn't be the first time!).
As Geoff Reedy writes (thanks, Geoff, for stating this so clearly):
Geoff> I think the issue is different from accessibility. As the
Geoff> identifier x is not a member (val, var or def) of class C there
Geoff> should not be anything to import regardless of accessibility. In
Geoff> other words, while the java signature for the class must contain
Geoff> a field for x, the scala signature should not. I.e. fields with
Geoff> the paramaccessor flag should not be selectable.
Fri, 2009-12-11, 16:27
#5
Re: Visibility of class parameters
On Thu, Dec 03, 2009 at 07:24:28PM -0600, Seth Tisue said
> >>>>> "martin" == martin odersky writes:
>
> martin> Note that nothing is said about whether the member needs to be
> martin> accessible.
>
> I understand that visibility and accessibility are different, and that
> something can be visible without being accessible.
>
> In this case, though, why is x visible outside C? I think it should not
> be, and I can find nothing in the spec to justify x's visibility
> (though, am I missing something? it wouldn't be the first time!).
>
> As Geoff Reedy writes (thanks, Geoff, for stating this so clearly):
>
> Geoff> I think the issue is different from accessibility. As the
> Geoff> identifier x is not a member (val, var or def) of class C there
> Geoff> should not be anything to import regardless of accessibility. In
> Geoff> other words, while the java signature for the class must contain
> Geoff> a field for x, the scala signature should not. I.e. fields with
> Geoff> the paramaccessor flag should not be selectable.
So what's the verdict? Is this a bug that should be filed?
Fri, 2009-12-11, 16:47
#6
Re: Visibility of class parameters
>>>>> "Geoff" == Geoff Reedy writes:
Geoff> So what's the verdict? Is this a bug that should be filed?
No verdict, but I filed it anyway:
http://lampsvn.epfl.ch/trac/scala/ticket/2773
On Thu, Dec 03, 2009 at 03:54:14PM -0600, Seth Tisue said
> Is this covered in the spec? Section 5.3, Class Definitions, covers
> class parameters but it doesn't talk about what happens when a class
> parameter is referred to in one of the class's methods. (I can't find a
> section that does talk about that.)
I believe this is the same oddity discussed in
http://old.nabble.com/strange-%22reassignment-to-val%22-error-when-writi...