On Feb 27, 2015, at 7:48 PM, Xueming Shen <[email protected]> wrote:

> On 02/27/2015 10:34 AM, Paul Sandoz wrote:
>> On Feb 27, 2015, at 7:18 PM, Xueming Shen<[email protected]>  wrote:
>> 
>>> Hi Paul,
>>> 
>>> 1133      * @param  replacer
>>> 1134      *         The function to be applied to the match result of this 
>>> matcher
>>> 1135      *         that returns a replacement string.
>>> 1136      *
>>> 1137      *<p>   The function should not modify this matcher's state during
>>> 1138      *         replacement.  This method will, on a best-effort basis, 
>>> throw a
>>> 1139      *         {@link java.util.ConcurrentModificationException} if 
>>> such
>>> 1140      *         modification is detected.
>>> 1141      *
>>> 1142      *<p>   The state of the match result is guaranteed to be constant
>>> 1143      *         only for the duration of the function call and only if 
>>> the
>>> 1144      *         function does not modify this matcher's state.
>>> 
>>> 
>>> 1151      * @throws ConcurrentModificationException if it is detected, on a
>>> 1152      *         best-effort basis, that the replacer function modified 
>>> this
>>> 1153      *         matcher's state
>>> 
>>> 
>>> Just wonder from API point of view, in theory the replacer should not be 
>>> able to modify
>>> this matcher's state via a MatchResult, it is the side-effect of our 
>>> implementation detail
>>> that happens to return "this matcher" as a MatchResult. For example, it 
>>> should be possible
>>> to simply return a wrapper MatchResult on top of this matcher to only 
>>> expose the read-only
>>> MatchResult methods, so the "replacer" will never be possible to modify the 
>>> "matcher".
>>> 
>> It's not really about casting a MatchResult to Matcher it's about the 
>> function capturing the Matcher instance and operating on it.
>> 
> 
> The "replacer" does not have an explicit reference to the matcher...

Correct, just like a Consumer does not have an Iterable with Iterable.forEach.


> and
> from the implementation it is not really about the "replacer" to change the
> state of the matcher, but the matcher's state gets changed during "replacing"?

It's both, A function could do something silly, such as:

 Matcher m = ...
 m.replaceAll(mr -> { 
    m.find(); // bad
    // mr state is now messed up
    return mr.group();
 });


 List l = ...
 m.replaceAll(mr -> { 
  l.add(mr); // bad, mr escapes
  return mr.group();
 });


> it might be more clear/obvious to move those warning notes up to the method
> doc as "the matcher state should not be updated/changed during the replaceAll
> is invoked..."?
> 

Moving them up would be clearer, i will do that.

What about a light wright immutable MatchResult? is that possible?

Paul.

Reply via email to