What is the meaning of private[context] - scala

I'm trying to wrap my head around the Scala language and figured the best way to learn is to put it into practice. When copy pasting code between a Java project (Spring) and my Scala project the IDE did a conversion I do not understand. Searching for it on the internet and in the docs gave me nothing to work with unfortunately.
The code:
#Bean private[context] def passwordEncoder: PasswordEncoder = {
return new BCryptPasswordEncoder
}
When compiling the above code the compiler complains:
`error: context is not an enclosing class`
Can anybody explain what the private[context] part means?

context is just a placeholder, where you can fill in the context in which you'd like the method to be private. This is optional though. If you don't specify the context, the member becomes "class-private", which afaik behaves like private does in Java.
Background: Scala offers more than one degree of access specification: the object-private specification, i.e. private[this], stipulates that the member in question can only be seen by members called on that same object, not from different objects, even if they are of the same type. Instead of this you can also use a package name or even root, which is an alias for the root namespace.
More information on this can be found in "Section 5.2 - Modifiers" of the Scala Language Reference:
The private modifier can be used with any definition or declaration in a template.
[...]
The modifier can be qualified with an identifier C (e.g. private[C]) that must denote a class or package enclosing the definition. Members labeled with such a modifier are accessible respectively only from code inside the package C or only from code inside the class C and its companion module (§5.4).

Related

What is the difference between ::class and ::class.java in Kotlin?

In Java, we write .class (for example: String.class) to get information about the given class. In Kotlin you can write ::class or ::class.java. What is the difference between them?
By using ::class, you get an instance of KClass. It is Kotlin Reflection API, that can handle Kotlin features like properties, data classes, etc.
By using ::class.java, you get an instance of Class. It is Java Reflection API, that interops with any Java reflection code, but can't work with some Kotlin features.
First you need to understand about Reflection. According to the docs:
Reflection is a set of language and library features that allows for introspecting the structure of your own program at runtime.
In simple words, it gives you the ability to get the code you have written i.e., the class name you have defined, the function name you have defined, etc. Everything you have written, you can access all these at runtime using Reflection.
::class and ::class.java are basic features of Reflection.
::class gives you a KClass<T> reference and ::class.java gives you Class<T> reference.
Example,
val a = MyClass::class
can be interpreted as
val a = KClass<MyClass>()
Note: Above code is not syntactically correct, because KClass is an interface and interfaces cannot be instantiated. It is just to give you an idea.
A Class<T> class gives you information about the metadata of the T class like interfaces it is implementing, its functions' names, its package name, etc.
KClass is similar to Class but it gives information about some more properties(Kotlin related properties) than Class. All the information a KClass<T> reference can give you about the T class are listed here https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/#properties
According to the Kotlin documentation, when we create an object using any class type as below the reference type will be type of KClass.
val c = MyClass::class // reference type of KClass
Kotlin class reference is not the same as a Java class reference. To get a Java class reference, use the .java property on a KClass instance.
val c = MyClass::class.java // reference type of Class Java

Scala parameters for access modifiers?

What is the difference between
class Test {
private[this] val foo = 0
}
vs
class Test {
private val foo = 0
}
What all can go inside the []? Also, what should I search for when I want to look up the specs of this? I tried Googling various combinations of "scala access modifier arguments/parametrized scala access modifier" and nothing came up.
what should I search for when I want to look up the specs of this?
In The Scala Language Specification it is defined as "access modifier" and "access qualifier" (see BNF in §5.2).
What is the difference between
...
What all can go inside the []?
You can put class name, package name or this there. Here is a relevant quote from language specs that explains this (see §5.2 for more details):
The modifier can be qualified with an identifier C (e.g. private[C ]) that must
denote a class or package enclosing the definition. Members labeled with
such a modifier are accessible respectively only from code inside the package
C or only from code inside the class C and its companion module (§5.4).
An different form of qualification is private[this]. A member M marked
with this modifier is called object-protected; it can be accessed only from
within the object in which it is defined. That is, a selection p.M is only legal if the prefix is this or O.this, for some class O enclosing the reference. In
addition, the restrictions for unqualified private apply.
The first one is private for instance class, second is for class. If you use second version you have access from another instance of Test class (it's usefull for equals method or similiar).

Scala package private with duplicate name in package hierarchy

So I understand that in Scala, you can define something private within the scope of a specific package by adding the modifier private[packagename] where packagename is (obviously) the name of the package that you wish the reference to be private to.
So, for instance, let's say I have a package com.mycompany.usefulname with some class that has a field declared private[mycompany] - this will be accessible within all things in the com.mycompany.usefulname, as well as other things like perhaps com.mycompany.othername (or things simply in the com.mycompany, if for some reason I put something there).
What I'm wondering is this: if I do an awful design, where I have two different levels of my hierarchy using the same name, such as a package com.mycompany.mycompany, is there a way to specify which mycompany I would want something to be private within? Based on Package private modifier in Scala 2.8, it doesn't seem to be valid to specific private[com.mycompany], so how could I specify which one it would be?
Just to be clear, this is purely out of curiosity, and I'm not actually trying to make something with such an ambiguous name in the class hierarchy.
EDIT: To actually see what this does, I implemented the following hierarchy:
mycompany
mycompany
InnerObject.scala
usefulname
InnerObject2.scala
OuterObject.scala
InnerObject.scala is as follows:
object InnerObject {
private val privateVal = 7
private[mycompany] val packagePrivateVal = 8
val regularVal = 9
}
InnerObject2.scala is virtually identical:
object InnerObject2 {
private val privateVal = 7
private[mycompany] val packagePrivateVal = 8
val regularVal = 9
}
from OuterObject, I could reference:
InnerObject.regularVal
InnerObject2.packagePrivateVal
InnerObject2.regularVal
The regularVal isn't surprising, as this is public. The package private seems to be going up the hierarchy until it finds the first instance that matches the declaration of mycompany. So, can anyone tell me if/how to make it reference the outer one, rather than the inner one?
Here is the relevant excerpt (the example under the linked anchor) from the Scala language specification:
The following code illustrates the use of qualified private:
package outerpkg.innerpkg
class Outer {
class Inner {
private[Outer] def f()
private[innerpkg] def g()
private[outerpkg] def h()
}
}
Here, accesses to the method f can appear anywhere within OuterClass, but not outside it. Accesses to method g can appear anywhere within the package outerpkg.innerpkg, as would be the case for package-private methods in Java. Finally, accesses to method h can appear anywhere within package outerpkg, including packages contained in it.
There is no other mention of package-private access modifiers anywhere in the specs, at all. From this, I'd gather there is no way to deal with duplicate path nodes in the package name, and Scala will take the inner-most name that it finds, as you say.
In my opinion, that's a good thing, because duplicate names are redundant and confusing.

Why are classes inside Scala package objects dispreferred?

Starting with 2.10, -Xlint complains about classes defined inside of package objects. But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name, except a lot more convenient.
In my opinion, one of the serious design flaws in Scala is the inability to put anything other than a class-like entity (e.g. variable declarations, function definitions) at top level of a file. Instead, you're forced to put them into a separate ''package object'' (often in package.scala), separate from the rest of the code that they belong with and violating a basic programming rule which is that conceptually related code should be physically related as well. I don't see any reason why Scala can't conceptually allow anything at top level that it allows at lower levels, and anything non-class-like automatically gets placed into the package object, so that users never have to worry about it.
For example, in my case I have a util package, and under it I have a number of subpackages (util.io, util.text, util.time, util.os, util.math, util.distances, etc.) that group heterogeneous collections of functions, classes and sometimes variables that are semantically related. I currently store all the various functions, classes, etc. in a package object sitting in a file called io.scala or text.scala or whatever, in the util directory. This works great and it's very convenient because of the way functions and classes can be mixed, e.g. I can do something like:
package object math {
// Coordinates on a sphere
case class SphereCoord(lat: Double, long: Double) { ... }
// great-circle distance between two points
def spheredist(a: SphereCoord, b: SphereCoord) = ...
// Area of rectangle running along latitude/longitude lines
def rectArea(topleft: SphereCoord, botright: SphereCoord) = ...
// ...
// ...
// Exact-decimal functions
class DecimalInexactError extends Exception
// Format floating point value in decimal, error if can't do exactly
formatDecimalExactly(val num: Double) = ...
// ...
// ...
}
Without this, I would have to split the code up inconveniently according to fun vs. class rather than by semantics. The alternative, I suppose, is to put them in a normal object -- kind of defeating the purpose of having package objects in the first place.
But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name,
Precisely. The semantics are (currently) the same, so if you favor defining a class inside a package object, there should be a good reason. But the reality is that there is at least one good reason no to (keep reading).
except a lot more convenient
How is that more convenient?
If you are doing this:
package object mypkg {
class MyClass
}
You can just as well do the following:
package mypkg {
class MyClass
}
You'll even save a few characters in the process :)
Now, a good and concrete reason not to go overboard with package objects is that while packages are open, package objects are not.
A common scenario would be to have your code dispatched among several projects, with each project defining classes in the same package. No problem here.
On the other hand, a package object is (like any object) closed (as the spec puts it "There can be only one package object per package"). In other words,
you will only be able to define a package object in one of your projects.
If you attempt to define a package object for the same package in two distinct projects, bad things will happen, as you will effectively end up with two
distinct versions of the same JVM class (n our case you would end up with two "mypkg.class" files).
Depending on the cases you might end up with the compiler complaining that it cannot find something that you defined in the first version of your package object,
or get a "bad symbolic reference" error, or potentially even a runtime error. This is a general limitation of package objects, so you have to be aware of it.
In the case of defining classes inside a package object, the solution is simple: don't do it (given that you won't gain anything substantial compared to just defining the class as a top level).
For type aliase, vals and vars, we don't have such a luxuary, so in this case it is a matter of weighing whether the syntactic convenience (compared to defining them in an object) is worth it, and then take care not to define duplicate package objects.
I have not found a good answer to why this semantically equivalent operation would generate a lint warning. Methinks this is a lint bug. The only thing that I have found that must not be placed inside a package object (vs inside a plain package) is an object that implements main (or extends App).
Note that -Xlint also complains about implicit classes declared inside package objects, even though they cannot be declared at package scope. (See http://docs.scala-lang.org/overviews/core/implicit-classes.html for the rules on implicit classes.)
I figured out a trick that allows for all the benefits of package objects without the complaints about deprecation. In place of
package object foo {
...
}
you can do
protected class FooPackage {
...
}
package object foo extends FooPackage { }
Works the same but no complaint. Clear sign that the complaint itself is bogus.

Private scoping with square brackets (private[...]) in Scala

I've come across the following syntax while looking through the Gatling source code:
private[http] def build = {
// ...
}
What is the syntax inside square brackets?
When I click through it in my IDE it is an alias to a fully qualified package (com.excilys.ebi.gatling.http) but I can't find where that alias was defined.
See the scala reference, specifically, chapter 5.2. Some excerpt:
The private modifier can be used with any definition or declaration in a template. Such members can be accessed only from within the directly enclosing template and its companion module or companion class (§5.4). They are
not inherited by subclasses and they may not override definitions in parent
classes.
The modifier can be qualified with an identifier C (e.g. private[C]) that must
denote a class or package enclosing the definition. Members labeled with
such a modifier are accessible respectively only from code inside the package C or only from code inside the class C and its companion module (§5.4).
Such members are also inherited only from templates inside C.
In short: this is used for scope protection:
private[C] means that access is private "up to" C, where C is the
corresponding package, class or singleton object.
Same to protected[C]
protected[C]: access is protected "up to" C, where C is the
corresponding package, class or singleton object.