0
votes

I have a scalding job. I've create two traits A, B each trait has companion object A, B with implict wrap for trait and Pipe.

Job compiles successfully, when I use only one trait. When I import both traits, compilation fails. It says that all methods from traits are "is not a member of cascading.pipe.Pipe"

Why? what do I do wrong? If I comment import of A. or B., it compiles.

class ScaldingJob(args: Args) extends Job(args) {
  import logic.TraitA._
  import logic.TraitB._

  val pipeA = UnpackedAvroSource(args("input1")).read
              .methodFromTraitA

  val pipeB = UnpackedAvroSource(args("input2")).read
              .methodFromTraitB           
}


trait TraitA extends FieldConversions {

  def self: RichPipe

  def methodFromTraitA : Pipe = self
    .map(/***/)  
}

object TraitA {

  implicit class TraitAWrapper(val self: RichPipe) extends AnyRef with TraitA
  implicit def wrapPipe(self: cascading.pipe.Pipe): TraitAWrapper = new TraitAWrapper(new RichPipe(self))
}


trait TraitB extends FieldConversions {

  def self: RichPipe

  def methodFromTraitB : Pipe = self
    .map(/***/)  
}

object TraitB {

  implicit class TraitBWrapper(val self: RichPipe) extends AnyRef with TraitB
  implicit def wrapPipe(self: cascading.pipe.Pipe): TraitBWrapper = new TraitBWrapper(new RichPipe(self))
}

UPD, I've changed the code:

  val readInput1: TraitA= UnpackedAvroSource(args("input1")).read
  val pipeA = readInput1.methodFromTraitA

  val pipeB = UnpackedAvroSource(args("input2")).read
          .methodFromTraitB      

and removed implicits:

class TraitAWrapper(val self: RichPipe) extends AnyRef with TraitA class TraitBWrapper(val self: RichPipe) extends AnyRef with TraitB

Now compiler complains:

val readInput1: TraitA= UnpackedAvroSource(args("input1")).read
      val pipeA = readInput1.methodFromTraitA
                            .otherMethodFromTraitA

value otherMethodFromTraitA is not a member of cascading.pipe.Pipe Possible cause: maybe a semicolon is missing before `value otherMethodFromTraitA'?

1
it's easier to answer is you post some example codeGabriele Petronella
I've added a code sample. So If i comment import TraitA/TraitB and pipeA/pipeB. Code compiles and trait unit-tests run. When both traits are used in ScaldingJob i get complie error... Look like the problem is in poor scala knowledgeCapacytron

1 Answers

1
votes

Probably not the answer you were expecting but if you give a hint to the Scala compiler, it would be able to compile:

class ScaldingJob(args: Args) extends Job(args) {
  import logic.TraitA._
  import logic.TraitB._

  val readInput1: TraitA= UnpackedAvroSource(args("input1")).read
  val pipeA = readInput1.methodFromTraitA

  val pipeB = UnpackedAvroSource(args("input2")).read
          .methodFromTraitB           
}

You would also need to remove "implicit" next to TraitAWrapper and TraitBWrapper.

Could be that there is too much going on with implicits and compiler is not able to handle all of it