In my Node.js project, I have normal class definitions like:
/**
* My awesome class.
* #constructor
*/
var MyClass = function MyClass() {}
And in another file I require it like:
var MyClass = require('./myclass.js').MyClass;
But sometimes JSDoc finds the require statement and only documents MyClass as a global variable. How to make JSDoc always document the class definition and ignore the variables defined in require statements?
Related
I found docs for the #define scaladoc macro but they don't go into any depth.
What I'm trying to do is write documentation in a base class/trait in a generic way, with #defined variables so that the wording in the generated docs for the subclasses makes sense.
I've distilled this down to an example of something I would have expected to work, but doesn't:
/**
* #define Word base-word
*/
class DocTestBase {
/** Does a $Word
*
* #return
*/
def foo = 1
}
/**
* #define Word subclass word!
*/
class DocTestSubclass extends DocTestBase
With the above, I'd expect the generated documentation for DocTestSubclass#foo to say "Does a subclass word!", but as you can see below, it doesn't.
FWIW I also tried this on Scala 2.12 but the result is the same.
How do I get this to work as I expect? Is this a bug in scaladoc?
I have written the following code:
class a {
object c {
var a = "STATIC"
def m() = print("STATIC METHOD")
var f = () => print("STATIC FUNCTION")
}
}
object m {
def main(args: Array[String]) = {
var o = new a()
o.c.m()
}
}
Can I say that the variables, functions and methods that are declared in object c can be static?
If I change name of object c with a then will the object becomes a companion object?
Scala has no true meaning of 'static' that Java does.
The fact that objects have a backing on the JVM that uses static methods / fields is a leaking implementation detail that you only need to deal with if using Java/JVM interop.
Unless you explicitly need that interop, you need to stop thinking of declared objects as 'static' and instead think of them as singletons within their given scope.
An inner object nested under a class, means that there is only ever going to be 1 instance of that object, for each class instance, unlike inner classes which could have multiple instances.
This applies at the top level as well, except that Scala can do additional compatibility with other JVM languages, and mark some of the methods/members as static.
Fields and methods in an object are how Scala declares things that you would have used static for in Java. I guess you can, for intuition sake, say that those fields are usually static (as in only one of those in a JVM at once).
However, in your example, you put an object inside a class, making it no longer static. You can easily check this with a few lines of code (that you can find here on Scastie).
class MyClass {
object Embedded {
val a = "field"
def m = println("method")
}
}
val a = new MyClass().Embedded
val b = new MyClass().Embedded
// prints "a and b are different objects"
if (a eq b)
println("a and b are the same object")
else
println("a and b are different objects")
Regarding your second question: no, class and object must be in the same scope in order for it to be a companion object. You can find more details on the Scala Language Specification.
I quote from there:
Generally, a companion module of a class is an object which has the same name as the class and is defined in the same scope and compilation unit. Conversely, the class is called the companion class of the module.
To answer you questions:
The methods and fields in a.c are not globally static because they need an instance of a to exist. If a were an object, a.c would be static too.
If you want to have a companion object with static fields and methods for your class a it has to be defined outside of a's code block, like this:
class a {
/* non-static stuff goes here */
}
object a {
/* static stuff goes there */
def m() = print("STATIC METHOD")
}
You must keep both in the same file, defining the object or the
class first doesn't matter, so it generally depend on a convention or what makes most sense depending on use case.
If you want to call the static method a.m inside the class a, you will still need to call it a.m and not just m. But the class a will be able to use private fields and methods of object a, because they are companions.
As others already said, static doesn't really exist in Scala, but the concept transpires from Java since Scala is in most cases compiled into java bytecode.
Last advice, the convention is usually the same in Scala and in Java for classes and object: the first-letter of their name should be uppercase (except in some advanced Scala cases)
I have read this article to better understand Scala scoping rules.
Everything seemed clear until I ran into some code on GitHub that was like this:
package x.y.z
private[z] class ExampleClass {
// class body
}
As you can see, we have a private top-level class, and there's an access qualifier to modify the scope of that class, but it's set to the very same package where the class is defined. If the access qualifier was set to an enclosing scope (e.g. package y) I would perfectly get it, but like this I can't understand the difference with simply declaring the class as private:
package x.y.z
private class ExampleClass {
// class body
}
So what is the difference between the two snippets posted above?
NOTE: I don't know if it's of any relevance, but in the same file a companion object for the class was defined and simply declared as private (with no access qualifiers).
In the example you provided both modifiers have the same effect. Difference would be more apparent if you had an enclosing class/object.
Compiles:
package x.y.z
object OuterExampleClass {
private[z] class ExampleClass()
}
object AnotherObject {
val ec = new OuterExampleClass.ExampleClass()
}
Fails to compile:
package x.y.z
object OuterExampleClass {
private class ExampleClass() // no [z] !!!
}
object AnotherObject {
val ec = new OuterExampleClass.ExampleClass() // error
}
with message:
class ExampleClass in object OuterExampleClass cannot be accessed in
object x.y.z.OuterExampleClass
Let's say I want an integer that supplies a square method.
Kotlin:
fun Int.square() = this * this
usage:
println("${20.square()}")
doc:
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
We would like to emphasize that extension functions are dispatched statically
My expectation would've been that they simply add it to the member functions of the extended class during compilation, but that is what they explicitly deny, so my next thought was it could be "sort of" like scala implicits.
Scala:
object IntExtensions{
implicit Class SquareableInt(i:Int){
def square = i*i
}
}
usage:
import IntExtensions._
and then
println(f"${20.square}")
doc:
An implicit class is desugared into a class and implicit method pairing, where the implciit method mimics the constructor of the class.
The generated implicit method will have the same name as the implicit class.
But scala implicits create a new class, that would disable the usage of this.
So ... how IS it that Kotlin extends classes? "Make callable" isn't telling me much.
In your case Kotlin just create simple utils-class with name "filename"Kt and static method "int square(int x)" (java pseudo-code)
From Java it look something like this
// filename int-utils.kt
final class IntUtilsKt {
public static int square(int x) {
return x * x;
}
}
And after this all calls to
val result = 20.square()
will be transformed (on byte-code level) to
val result = IntUtilsKt.square(20);
P.S.
You can see it yourself using IDEA action "Show Kotlin byte-code"
Defining data members in a class that can be publicly accessed/modified
var _foo: Int = _
def foo_(foo: Int) = _foo = foo // setter function
def foo = _foo // getter function
Is it a good practice to convert this using annotation #BeanProperty?
import scala.reflect.BeanProperty
#BeanProperty var foo: Int = _
and when to use this annotation and when not to?
There's some redundancy in your first example, since defining a var already results in the generation of getters and setters. For example, if we compile this class:
class Foo {
var foo: Int = _
}
Then javap -private Foo shows the following:
public class Foo {
private int foo;
public int foo();
public void foo_$eq(int);
public Foo();
}
Unless you have custom logic that you need to fit into your getters or setters (in which case it's often a good idea to consider more descriptive method names, anyway), you shouldn't need to define them manually.
The scala.reflect.BeanProperty annotation (or scala.beans.BeanProperty on 2.11) doesn't have any effect on the generation of the foo() and foo_$eq(int) methods—the compiler will generate these for a var foo: Int whether or not you use the annotation. The annotation simply adds getFoo and setFoo aliases for these methods. If you need these aliases, use the annotation, and if you don't, don't.
To summarize best practices:
Don't use var.
If you have to use var, you can (and should) avoid defining your own getters and setters.
Use the BeanProperty annotation only if you're implementing an interface with getFoo and setFoo-style method signatures, or if you're expecting your code to be called from Java (where calling methods with names like foo_$eq is inconvenient).
#BeanProperty is meant for Java interoperability, in particular with reflection-based Java frameworks expecting get and set methods.
Do not use it if you're staying in the Scala world. Use Scala getters (def foo) and setters (def foo_=) instead.