Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6335269
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T18:49:21+00:00 2026-05-24T18:49:21+00:00

Consider this (very ugly code): object ExternalReferences2 { import java.util.regex._ implicit def symbol2string(sym: Symbol)

  • 0

Consider this (very ugly code):

object ExternalReferences2 {
  import java.util.regex._

  implicit def symbol2string(sym: Symbol) = sym.name

  object Mapping {
    def fromXml(mapping: scala.xml.NodeSeq) = {
      new Mapping(mapping \ 'vendor text, 
                  mapping \ 'match text, 
                  mapping \ 'format text)
    }
  }
  case class Mapping(vendor: String, 
                     matches: String,
                     format: String) extends PartialFunction[String, String] {
    private val pattern = Pattern.compile(matches)
    private var _currentMatcher: Matcher = null
    private def currentMatcher = 
      { println("Getting matcher: " + _currentMatcher); _currentMatcher }
    private def currentMatcher_=(matcher: Matcher) = 
      { println("Setting matcher: " + matcher); _currentMatcher = matcher }

    def isDefinedAt(entity: String) = 
      { currentMatcher = pattern.matcher(entity); currentMatcher.matches }

    def apply(entity: String) = apply

    def apply = {
      val range = 0 until currentMatcher.groupCount()
      val groups = range 
                     map (currentMatcher.group(_)) 
                     filterNot (_ == null) 
                     map (_.replace('.', '/'))
      format.format(groups: _*)
    }
  }

  val config =
    <external-links>
      <mapping>
        <vendor>OpenJDK</vendor>
        <match>{ """^(javax?|sunw?|com.sun|org\.(ietf\.jgss|omg|w3c\.dom|xml\.sax))(\.[^.]+)+$""" }</match>
        <format>{ "http://download.oracle.com/javase/7/docs/api/%s.html" }</format>
      </mapping>
    </external-links>

  def getLinkNew(entity: String) =
     (config \ 'mapping) 
       collectFirst({ case m => Mapping.fromXml(m)})
       map(_.apply)

  def getLinkOld(entity: String) =
    (config \ 'mapping).view 
      map(m => Mapping.fromXml(m)) 
      find(_.isDefinedAt(entity)) 
      map(_.apply)
}

I tried to improve the getLinkOld method by using collectFirst as shown in getLinkNew, but I always get a NullPointerException because _currentMatcher is still set to null

scala> ExternalReferences2.getLinkNew("java.util.Date")
Getting matcher: null
java.lang.NullPointerException
    at ExternalReferences2$Mapping.apply(<console>:32)
    at ExternalReferences2$$anonfun$getLinkNew$2.apply(<console>:58)
    at ExternalReferences2$$anonfun$getLinkNew$2.apply(<console>:58)
    at scala.Option.map(Option.scala:131)
    at ExternalReferences2$.getLinkNew(<console>:58)
    at .<init>(<console>:13)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)

while it works perfectly with getLinkOld.

What is the problem here?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T18:49:22+00:00Added an answer on May 24, 2026 at 6:49 pm

    Your matcher is created as a side-effect in isDefined. Passing side effecting functions to routine such as map is usually a recipe for disaster, but this is not even what happens here. Your code requires isDefined to have been called just before apply is, with the same argument. That makes your code very fragile, and that is what you should change.

    Clients of PartialFunction do not have to do follow that protocol in general. Imagine for instance

    if (f.isDefinedAt(x) && f.isDefinedAt(y)) {fx = f(x); fy = f(y)}. 
    

    And here the code that calls apply is not even yours, but the collection classes’, so you do not control what happens.

    Your specific problem in getLinkNew is that isDefined is simply never called.The PartialFunction argument of collectFirst is {case m => ...}. The isDefined that is called is the isDefined of this function. As m is an irrefutable pattern, it is allways true, and collectFirst will always return the first element if there is one. That the partial function returns another partial function (the Mapping) which happens not to be defined at m, is irrelevant.

    Edit – Possible workaround

    A very light change would be to check whether a matcher is available and create it if it is not. Better, keep the entity string that has been used to create it too, so that you can check it is the proper one. This should make the side effect benign as long as there is no multithreading. But the way, do not use null, use Option, so the compiler will not let you ignore the possibility that it may be None.

    var _currentMatcher : Option[(String, Matcher)] = None
    def currentMatcher(entity: String) : Matcher = _currentMatcher match{
      case Some(e,m) if e == entity => m
      case _ => {
        _currentMatcher = (entity, pattern.matcher(entity))
        _currentmatcher._2
      }
    }
    

    Edit again. Stupid me

    Sorry, the so called workaround indeed makes the class safer, but it does not make the collectFirst solution work. Again, the case m => partial function is always defined (note: entity does not even appears in your getLinkNew code, which should be worrying). The problem is that one would need a PartialFunction of a NodeSeq (not of entity, which will be known to the function, but not passed as argument). isDefined will be called, then apply. The pattern and the matcher depends on the NodeSeq, so they cannnot be created beforehand, but only in isDefined and/or apply. In the same spirit, you can cache what is computed in isDefined to reuse in Apply. This is definitely not pretty

    def linkFor(entity: String) = new PartialFunction[NodeSeq, String] {
      var _matcher : Option[String, Matcher] = None
      def matcher(regexp: String) = _matcher match {
        case Some(r, m) where r == regexp => m
        case None => {
          val pattern = Pattern.compile(regexp)
          _matcher = (regexp, pattern.matcher(entity))
          _matcher._2
        }
      }
      def isDefined(mapping: NodeSeq) = {
        matcher(mapping \ "match" text).matches
      }
      def apply(mapping: NodeSeq) = {
         // call matcher(...), it is likely to reuse previous matcher, build result
      }
    
    }
    

    You use that with (config \ mapping).collectFirst(linkFor(entity))

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Consider this code... using System.Threading; //... Timer someWork = new Timer( delegate(object state) {
Consider this code (Java, specifically): public int doSomething() { doA(); try { doB(); }
consider this very short T-SQL code that does a test on a nullable column
Consider this (horrible, terrible, no good, very bad) code structure: #define foo(x) // commented
This may seem a very silly question. Consider this: I have a simple Boolean
This is a very basic question, so please bear with me. Consider the following
consider this code block public void ManageInstalledComponentsUpdate() { IUpdateView view = new UpdaterForm(); BackgroundWorker
Consider this code: var query = db.Table .Where(t => SomeCondition(t)) .AsEnumerable(); int recordCount =
Consider this very small contrived subset of my schema: SensorType1 ID : PK SensorType2
consider this simple and pointless code. #include <iostream> struct A { template<int N> void

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.