-1

I have a break point set at line s = new Array(capacity) but it seems like the apply method is not being called. Have I implemented it correctly ?

object StacksAndQueuesTest {

    def main(args: Array[String]) {

      val f = new FixedCapacityStackOfStrings(3)
      println(f.isEmpty);

    }

}

class FixedCapacityStackOfStrings(capacity : Int) {

  var s : Array[String] = _
  var N : Int = 0

  def isEmpty : Boolean = {
    N == 0
  }

  def push(item : String) = {
    this.N = N + 1
    s(N) = item
  }

  def pop = {
    this.N = N - 1
    val item : String = s(N)

    /**
     * Setting this object to null so
     * that JVM garbage collection can clean it up
     */
    s(N) = null
    item
  }

  object FixedCapacityStackOfStrings {
  def apply(capacity : Int){
   s = new Array(capacity)
  }
}

}
blue-sky
  • 51,962
  • 152
  • 427
  • 752
  • 1
    What is apply even doing ? s does not even exist in your object. Are you trying to use apply to create a new instance of FixedCapacityStackOfStrings ? – vptheron Apr 10 '13 at 20:23
  • Does this even compile? `s` is not in scope in the `object` - it's an instance variable in the `class`. – Boris the Spider Apr 10 '13 at 20:24
  • It's compiling because companion object has access to fields of companion class. See: http://stackoverflow.com/questions/11604320/whats-the-difference-between-a-class-with-a-companion-object-and-a-class-and-ob – Infinity Apr 10 '13 at 20:35
  • But s has to be part of an instance of FixedCapacityStackOfStrings, where is the instance in the apply method of the object ? This does not compile. – vptheron Apr 10 '13 at 20:37
  • @vtheron it compiled for me using Eclipse Juno with scala 2.10.0 . The scala plugin is marked as "experimental" for Juno so perhaps its a plugin issue – blue-sky Apr 10 '13 at 21:14

2 Answers2

2

In your case the companion object may not be of much help except to avoid newoperator

class FixedCapacityStackOfStrings(capacity: Int) {
  var s: Array[String] = new Array(capacity)
  var N: Int = 0

  def isEmpty: Boolean = {
    N == 0
  }

  def push(item: String) = {
    this.N = N + 1
    s(N) = item
  }

  def pop = {
    this.N = N - 1
    val item: String = s(N)

    /**
     * Setting this object to null so
     * that JVM garbage collection can clean it up
     */
    s(N) = null
    item
  }
}

object FixedCapacityStackOfStrings {
  def apply(capacity: Int) = {
    println("Invoked apply()")
    new FixedCapacityStackOfStrings(capacity)
  }

  def main(args: Array[String]){
   val f = FixedCapacityStackOfStrings(5)
   println(f)
  }
}

And then you can use it like

val f = FixedCapacityStackOfStrings(5)

Reimer Behrends
  • 8,600
  • 15
  • 19
Teja Kantamneni
  • 17,402
  • 12
  • 56
  • 86
  • thanks, did you try your code, the apply method does not seem to be invoked ? – blue-sky Apr 10 '13 at 20:31
  • yes it works when I remove the new keyword, but should'nt this work also ? : val f = new FixedCapacityStackOfStrings(3) – blue-sky Apr 10 '13 at 20:37
  • when you use new FixedCapacity...() you're calling the constructor of the *class*, when you use FixedCapacity...() (so, without the new) you are calling the apply method of the *object*. – vptheron Apr 10 '13 at 20:39
  • read about companion objects in scala, http://tutorials.jenkov.com/scala/singleton-and-companion-objects.html – Teja Kantamneni Apr 10 '13 at 20:39
  • @vtheron Ok, but how can I access the methods of class FixedCapacityStackOfStrings as once since I remove the 'new' keyword I no longer have an instance – blue-sky Apr 10 '13 at 20:41
  • assign it to a variable. `val f = new FixedCapacityStackOfStrings(capacity)`. Companion objects is similar to a factory class in java with static factory methods. They return you instances – Teja Kantamneni Apr 10 '13 at 20:43
  • In Teja's code, apply gives you an instance (notice that apply uses new internally), so when you do val f = FixedCapacityStackOfStrings(5) you are calling apply on the object, which calls the constructor of the class and gives you an instance. f is a valid instance. – vptheron Apr 10 '13 at 20:44
  • @vtheron if 'f' is a valid instance then why can I not invoke f.isEmpty when I use val f = FixedCapacityStackOfStrings(5) – blue-sky Apr 10 '13 at 20:48
  • you should be able to... any issue? – Teja Kantamneni Apr 10 '13 at 20:49
  • @Teja Kantamneni I am unable to invoke the methods within the FixedCapacityStackOfStrings object, can you type 'println(f.isEmpty)' and no syntax error is displayed in IDE? – blue-sky Apr 10 '13 at 21:21
0

For the calling object 'FixedCapacityStackOfStrings' to see the .isEmpty method I needed to use :

  def apply(capacity: Int) : FixedCapacityStackOfStrings = {
    new FixedCapacityStackOfStrings(capacity)
  }

instead of

  def apply(capacity: Int) {
    new FixedCapacityStackOfStrings(capacity)
  }
blue-sky
  • 51,962
  • 152
  • 427
  • 752