Community
Participate
Working Groups
When extracting a block of code that uses variables defined outside the scope of the extraction (eg, class members), those variables should be offered to be made parameters of the extracted method, rather than just copying over the variables. For example, suppose we want to extract this snippet to a method: CapturingArgumentsMatcher captureRunnableMatcher = new CapturingArgumentsMatcher(mocks); SlicedArgumentsMatcher matcher = new SlicedArgumentsMatcher( captureRunnableMatcher, MockControl.EQUALS_MATCHER); mockScheduledExecutorService.object.schedule((Runnable)null, AFTER_FILL_DELAY, TimeUnit.SECONDS); mockScheduledExecutorService.control.setMatcher(matcher); mockScheduledExecutorService.control.setReturnValue(mockScheduledFuture.object); The following variables, with their assoicated types, can be offered as parameters: 'mocks', '(Runnable)null', 'AFTER_FILL_DELAY', 'TimeUnit.SECONDS', 'mockScheduledFuture.object'. In fact, one of the main motivations for extract method is reuse the code in a parameterized fasion. (BTW, this has been a feature of Idea's extract method for as far back as I can remember. 3.0?. Definately 4.0.)
Not for 3.1 since we are in a mode where we only fix critical bugs. You can add the parameters "back" by introducing parameter.
Yes, I know it won't make into 3.1. But I wanted to capture this for possible scheduling into a future release.
The current solution is to first create local variables for these elements and then use extract local. Constant expressions like '(Runnable)null', 'AFTER_FILL_DELAY', 'TimeUnit.SECONDS' can be turned into parameters any time, using 'Introduce Parameter'. Things like 'mockScheduledFuture.object' and 'mocks' can only be turned into parameter if it is sure that they are constant during the calling sequence.
There is one problem with Introducing parameter after Extract. I get some code from a programmer who prefers the cut&paste&slightly_modify approach to building similar looking code pieces instead of bundling stuff into functions. Now if I have something (simplified case here) like: void f() { JPanel p=new JPanel(); JButton b1=new JButton("foo"); JButton b2=new JButton("bar"); p.add(b1); p.add(b2); } and I do an Extract Method on p.add(b1) Extract method makes b1 into a parameter, and then recognizes that p.add(b2) can be replaced as well. If I have the case JPanel p=new JPanel(); JButton b1=new JButton("foo"); JButton b2=new JButton("bar"); void f() { p.add(b1); p.add(b2); } Extract method will turn it into void f() { g(); p.add(b2); } void g() { p.add(b1); } Using "Introduce parameter" on b1 in method g will then turn this into f() { g(b1); p.add(b2); } private void g(JButton button) { p.add(button); } but I miss the opportunity to have eclipse change all other cases like p.add(b2) to g(b2). So Extract Method + Introduce Parameter is not a full substitute to an Extract method which gives me the possibility to tell right what variables I want to add as parameters. ...unless refactoring is augmented by "Apply method wherever it fits" which I could execute after "Introduce Parameter".