2

Trying to write a wrapper to slf4j.

wrote the methods. 2 of them are:

def logWarn(message: => String, arg1: => AnyRef) = { 

    if (logger.isWarnEnabled) {

        logger.warn(message, arg1)
    }
}

def logWarn(message: => String, args: => Array[AnyRef]) = {
    if (logger.isWarnEnabled) {
        logger.warn(message, args)
    }
}

This compiles nicely. Problem is trying to invoke:

logWarn("retried: {}. Error is: {}", Array[AnyRef](numOfRetries.toString(), e.toString()));

I would expect Scala to know I mean to call the second method above. for some reasons I get this error:

ambiguous reference to overloaded definition, both method logWarn in trait Slf4jLogger of type
(message: => String, args: => Array[AnyRef])Unit
and  method logWarn in trait Slf4jLogger of type (message: => String, arg1: => AnyRef)Unit 
match argument types (java.lang.String,Array[AnyRef])   

What's going on?

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
YaOg
  • 1,748
  • 5
  • 24
  • 43
  • See explanation in [http://stackoverflow.com/questions/4325086/why-is-scalas-behavior-in-case-of-overloading-with-by-name-parameters-different][1] [1]: http://stackoverflow.com/questions/4325086/why-is-scalas-behavior-in-case-of-overloading-with-by-name-parameters-different – Shimi Bandiel Jun 07 '12 at 04:49

1 Answers1

1

Array[_] is a subtype of AnyRef, hence any call with a 2nd argument of type Array[AnyRef] would be valid for both methods.

Without by-name parameters, you could easily work around this by using varargs:

def logWarn(message: => String, args: AnyRef*) {
  if (logger.isWarnEnabled) {
    logger.warn(message, args)
  }
}

However by-name params aren't compatible with varargs (in 2.9.1 at least). This means that args: (=> AnyRef)* is not valid.

Ben James
  • 121,135
  • 26
  • 193
  • 155