Let's say we have
class A
{ ... };
class B
{ ... };
class C
{ ... };
and let's say we have a free-function like
C operator*(A, B)
{ .... }
Is there a way to make operator* to appear in the related functions section of all A, B and C ?
I tried \relatedalso, but it seem to work only once.
Where did you place \relatedalso - documentation of the class(es) or the operator?
You can insert \relates for eacht class at your operators documentation:
/** This is class A. */
class A
{
// ...
};
/** This is class B. */
class B
{
// ...
};
/** This is class C. */
class C
{
// ...
};
/**
* This is an operator.
*
* \relates A
* \relates B
* \relates C
*
* #param a Class A
* #param b Class B
* #return Something
*/
C operator*(A a, B b)
{
// ...
}
Doxygen (html):
Related Functions
(Note that these are not member functions.)
C operator* (A a, B b)
(operator* is linked to it's documentation)
Related
Sorry in advance about the title, I'm not sure if I'm using the correct terms.
/**
* #return {Object.<string, number>}
*/
function foo() {}
The tooltip in VSCode for the above looks like this:
function foo(): {
[x: string]: number;
}
How can I choose a different label than x, like baz? So that it looks like:
function foo(): {
[baz: string]: number;
}
/**
* #typedef {{ [baz: string]: number }} Thing
* #return {Thing}
*/
function foo() {}
I am trying to add the result of database to List. But I have one problem here. Elements are added to list and size is same as number of element at initial size. But while printing final size, it's always 0. I'm not sure what is the error.
Thanks in advance
#Singleton
class HomeController #Inject()(cc: ControllerComponents) extends AbstractController(cc) {
var result = ListBuffer[Item]()
val res = db.run(items.result)
for (r <- res) {
for (r1 <- r) {
result += r1
}
println("initial size = " + result.size)
}
/**
* Create an Action to render an HTML page.
*
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/`.
*/
def index() = Action { implicit request: Request[AnyContent] =>
println("final size = " + result.size)
Ok(views.html.index())
}
}
I'm using the play-slick plugin 3.0.1 with Play! 2.6.6 and seem to have run into a problem.
What I'm trying to do is to implement "grant" based permission system from a DB table containing several columns. Since this table can be broad, I wanted to find a way to programmatically generate column names and read bits from each column, and evaluate to the presence or absence of a grant.
For example, the table might look like:
granted_for grantee read write
id1 id2 1 0
Next I set things up like so:
import centralapp.api.string.CamelToUnderscore
import models.permissions.grants.Grant
import slick.ast.{BaseTypedType, TypedType}
import slick.jdbc
import slick.jdbc.JdbcType
import slick.jdbc.MySQLProfile.api._
import slick.lifted.ProvenShape
trait HasName {
/**
* #note "HasName"
*/
def simpleName: String = getClass.getSimpleName.replaceAll("[^a-zA-Z0-9_]", "")
/**
* #note "has_name"
*/
def classNameLower: String = simpleName.toUnderscoreLower
/**
* #note "HAS_NAME"
*/
def classNameUpper: String = simpleName.toUnderscoreUpper
}
And then a trait that defines a DB column abstraction:
trait DBColumn[C, T <: Table[_]] extends HasName {
/**
* the name of the column
*/
def columnName: String = classNameLower
/**
* get the column representation
*
* #param c the TypedType representation of this column's type
* #param table the table for which the column is being generated
* #return a Rep[C] (representation of type C)
*/
def col(implicit c: TypedType[C], table: T): Rep[C] = table.column[C](columnName)
}
And then use that to generate "Grant" column mappings:
package object db {
/**
* creates a grant column mapping from a boolean column for a given grant
*
* #param g the grant to obtain if the column is set to "true"
* #tparam G the subtype of the grant
* #return the JDBC type for the desired value
*/
def optGrantFromBoolCol[G <: Grant](g: G): JdbcType[Option[G]] with BaseTypedType[Option[G]] = MappedColumnType.base[Option[G], Boolean](
_.isDefined,
{
case true => Some(g)
case false => None
}
)
abstract class GrantCol[G <: Grant, T <: Table[_]](grant: G) extends DBColumn[Option[G], T] {
// class Grant also extends HasName; here I want to ensure the column name is exactly the same as the string representation of the grant.
override def columnName: String = grant.classNameLower
/**
* get the column representation
*
* #param table the table for which the column is being generated
* #return a Rep[C] (representation of type C)
*/
def grantCol(implicit table: T): jdbc.MySQLProfile.api.Rep[Option[G]] = col(optGrantFromBoolCol(grant), table)
}
}
And then I tried to use this like so:
object Columns {
case object GrantedFor extends DBColumn[String, MyTable]
case object Grantee extends DBColumn[String, MyTable]
case object Read extends GrantCol[UserGrant, MyTable](usergrants.Read)
}
// and then used it in a table:
class MyTable(tag: Tag) extends Table[SomeClass](tag, "my_table") {
implicit def table = this
val grantedFor = Columns.GrantedFor.col
val grantee = Columns.Grantee.col
val read = Columns.Read.grantCol
def * : ProvenShape[SomeClass] =
(grantedFor, grantee, read) <> // <- this is the problem: Cannot resolve symbol "<>"
(
???, // valid constructor from tuple
??? // valid unapply
)
def other : ProvenShape[OtherClass] =
(grantedFor, grantee) <> (
???,
???
)
}
As described in the comments, I see that the moment there's a "Grant" column in the tuple, the resolution for the <> symbol starts failing. I cannot seem to see what the problem here could be.
Any pointers?
I've found similar issues of this particular problem, however the problem was due to someone trying to instantiate T directly. Here I'm trying to create a trait that is a general interface to extend classes and store them automatically in a database such as Riak using classOf[T]. Using Scala 2.10.
Here's my code:
trait RiakWriteable[T] {
/**
* bucket name of data in Riak holding class data
*/
def bucketName: String
/**
* determine whether secondary indices will be added
*/
def enable2i: Boolean
/**
* the actual bucket
*/
val bucket: Bucket = enable2i match {
case true => DB.client.createBucket(bucketName).enableForSearch().execute()
case false => DB.client.createBucket(bucketName).disableSearch().execute()
}
/**
* register the scala module for Jackson
*/
val converter = {
val c = new JSONConverter[T](classOf[T], bucketName)
JSONConverter.registerJacksonModule(DefaultScalaModule)
c
}
/**
* store operation
*/
def store = bucket.store(this).withConverter(converter).withRetrier(DB.retrier).execute()
/**
* fetch operation
*/
def fetch(id: String): Option[T] = {
val u = bucket.fetch(id, classOf[T]).withConverter(converter).withRetrier(DB.retrier).r(DB.N_READ).execute()
u match {
case null => None
case _ => Some(u)
}
}
}
Compiler error is class type required but T found.
Example usage (pseudo-code):
class Foo
object Foo extends RiakWriteable[Foo]
Foo.store(object)
So I'm guessing that a manifest of T is not being properly defined. Do I need to implicitly define this somewhere?
Thanks!
Here's an intermediary solution, though it leaves out the converter registration (which I may leave permanently for this use case, not sure yet).
/**
* trait for adding write methods to classes
*/
trait RiakWriteable[T] {
/**
* bucket name of data in Riak holding class data
*/
def bucketName: String
/**
* determine whether secondary indices will be added
*/
def enable2i: Boolean
/**
* the actual bucket
*/
val bucket: Bucket = enable2i match {
case true => DB.client.createBucket(bucketName).enableForSearch().execute()
case false => DB.client.createBucket(bucketName).disableSearch().execute()
}
/**
* store operation
*/
def store(o: T) = bucket.store(o).withRetrier(DB.retrier).execute()
/**
* fetch operation
*/
def fetch(id: String)(implicit m: ClassTag[T]) = {
val u = bucket.fetch(id, classTag[T].runtimeClass).withRetrier(DB.retrier).r(DB.N_READ).execute()
u match {
case null => None
case _ => Some(u)
}
}
}
I'm implementing a class that acts as three stacks that rely on the same array (from Gayle Laakmann's cracking the coding interview).
I'm having trouble understanding why this code results in type mismatches:
class ThreeStacks[A, B, C ](val stackSize:Int = 1000) {
/**
* Push a value on to the first stack
* #param value value of type A */
def push1[A](value :A): Unit = stack1.push(value)
/**
* Push a value on to the second stack
* #param value value of type B */
def push2[B](value: B): Unit = stack2.push(value)
/**
* Push a value on to the third stack
* #param value value of type C */
def push3[C](value: C): Unit = stack3.push(value)
/**
* Pops the top value off the first stack
* #return Some(value) at the top of the stack, None if the stack is empty */
def pop1[A](): Option[A] = stack1.pop()
/**
* Pops the top value off the second stack
* #return Some(value) at the top of the stack, None if the stack is empty */
def pop2[B](): Option[B] = stack2.pop()
/**
* Pops the top value off the second stack
* #return Some(value) at the top of the stack, None if the stack is empty */
def pop3[C](): Option[C] = stack3.pop()
// the shared stacks
private val stack1 = SharedStack[A]()
private val stack2 = SharedStack[B]()
private val stack3 = SharedStack[C]()
// the shared stack class is simply a container for push and pop functions
class SharedStack[T](val push: T => Unit, val pop: () => Option[T])
// the sharedstack object is a factory setups a shared stack object with its proper push/pop functions that are received
// from the stackmemory instance
private object SharedStack{
val stackMemory = new StackMemory(stackSize)
def apply[T](): SharedStack[T] = {
val stackTuple = stackMemory.registerStack[T]()
new SharedStack(stackTuple._1, stackTuple._2)
}
}
// the memory object responsible for handling the sharing of the array
private class StackMemory(val stackSize: Int = 1000){
// helps prevent the conflict warnings with immutable and mutable collections
private val MutableMap = scala.collection.mutable.Map
// the array that contains the stack nodes
private val array = new Array[Option[StackNode[Any]]](stackSize)
// keeps track of the heads of all the stacks
private val registeredStackHeads = MutableMap[Int, Int]()
// an index to help assign every new stack a unique key
private var nextRegistrationIndex = 1
// a list of indices in the array that have been freed
private var freedIndices = List[Int]()
// the next available free index, increments till it reaches the end of the array, different from the freeIndices list
// in that it only is concerned with free cells while they are available at the end of the array
private var nextFreeIndex = 0
/**
* Registers a stack within the memory object and returns the push/pop functions
* #return the push/pop functions relevant for that stack */
def registerStack[T](): (T => Unit, () => Option[T]) = {
val index = nextRegistrationIndex
val noPreviousValueIndex = -1
// register the index in the stack heads with an empty value
registeredStackHeads(index) = noPreviousValueIndex
nextRegistrationIndex += 1
(push[T](index), pop[T](index) )
}
/**
* Returns the push function for a stack at the given index
* #param stackIndex the index of the requesting stack
* #return the push function for the stack */
def push[T](stackIndex: Int) = {
(value: T) => {
// get the indices and initialize a stack node
val headIndex = registeredStackHeads(stackIndex)
val index = nextAvailableIndex()
val stackNode = new StackNode[T](headIndex, value)
// store the new stack head and place it in to the array
registeredStackHeads(stackIndex) = index
array(index) = Some(stackNode)
}
}
/**
* The pop function for the stack at a given index
* #param stackIndex the index of the requesting stack
* #return the pop function for the stack */
def pop[T](stackIndex: Int): () => Option[T] = {
() => {
val headIndex = registeredStackHeads(stackIndex)
if(headIndex < 0) None else {
array(headIndex) match {
case Some(s : StackNode[T]) => {
registeredStackHeads(stackIndex) = s.previousIndex
freeIndex(headIndex)
Some(s.value)
}
case _ => None
}
}
}
}
// retrieve the next available index, throws an exception if there are no available indices
private def nextAvailableIndex():Int = {
// return a new index if the array isn't full otherwise throw an exception
def newIndex() : Int = {
if(nextFreeIndex >= stackSize){
throw new Exception("No more room in stack array available")
}
else{
val index = nextFreeIndex
nextFreeIndex += 1
index
}
}
// first check if any of the old indices have been freed
freedIndices match {
case Nil => newIndex()
case head::tail => freedIndices = tail; head
}
}
// frees an index and adds it to the free indices list
private def freeIndex(i: Int): Unit = {
if (i >= array.length) throw new ArrayIndexOutOfBoundsException("The index to be freed does not exist in the array")
array(i) = None
freedIndices = i::freedIndices
}
// covariant node that helps keep track of the previous index of the stack
private class StackNode[+S](val previousIndex: Int, val value: S)
}
}
The code works like its suppose to if I call stack1.push or stack1.pop but it causes type mismatches on wrappers push1 and pop1, why is this happenning?
example for push1:
type mismatch;
found : value.type (with underlying type A)
required: A
def push1[A](value :A): Unit = stack1.push(value)
example for pop1:
type mismatch;
found : Option[A(in class ThreeStacks)]
required: Option[A(in method pop1)]
def pop1[A](): Option[A] = stack1.pop()
The problem in your code is type parameter shadowing.
You have:
class ThreeStacks[A, B, C](val stackSize:Int = 1000) {
def push1[A](value: A): Unit = stack1.push(value)
...
}
It should be:
class ThreeStacks[A, B, C](val stackSize:Int = 1000) {
def push1(value: A): Unit = stack1.push(value)
...
}
The way you have done it, type parameter A of class ThreeStacks and type parameter A of method push1 are completely different ones and thus, are incompatible with each other.
The same applies to B and C.