Live data from Hacker News

Ask HN: How do you deal with 2000 line functions?

news.ycombinator.com

41–50 of 72 posts

Re: Ask HN: How do you deal with 2000 line functions?

#41

1. Unit tests. Otherwise modifying old code is full of potentially unforeseen landmines. 2. Read the function a few times to get a sense of what it's doing. 3. Break the function into blocks of statements that are performing a related task. 4. Factor those out into smaller functions. 5. Recursively repeat 3-5 until you're satisfied with the new functions' line count. > Should I tell my manager that the function needs…

I would add assertions in as well as you iterate. It will validate whether you understand the flow of information through the function.

Absolutely this. Not only do assertions make it easier to validate your understanding, they capture and preserve that understanding for future developers (including yourself, 6 weeks from now).

Assertions are comments which can always be trusted and which never get out of date. It baffles me that there's so much reluctance to use them (especially in dynamic languages).

Re: Ask HN: How do you deal with 2000 line functions?

#42
post #8

Earlier quoted context omitted.

Yep, this is the only way to handle these beasts. Don't touch anything. Make a ton of tests. Spend some time validating those tests. Get someone to write off that those tests are sufficient. Start refactoring!

For a function with 2,000 lines of code, we have to be honest with ourselves and accept that testing will never be sufficient; if there's 2,000 lines of code, you can bet good money that there's global state manipulation as well. Making the assumption that anybody is capable of sufficiently testing such functions and subsequently re-writing them will only introduce new bugs and old regressions. Seems harsh, but I've…

Test if you can, but I agree. Thinking unit testing will solve the problem can be incredibly naive especially if the code has lots of global state. Sometimes, just setting up all this state for a test is equivalent to rewriting the application. If the rest of the application is written like this, chances are this function makes a ton of 2k line calls of its own. Unit testing just might make sure you aren't doing something catastrophically dumb.

Re: Ask HN: How do you deal with 2000 line functions?

#43
I think making small opportunistic fixes is best. Do what you can do without massively delaying your work every time you need to work in that area of the code. That is, leave the code better than you found it, each time.

If you add the new logic this time and also split it into four 500-line methods and maybe a few extra tests, you have done quite a lot and it is likely doable within the time frame of the work you are doing.

But

If there are zero tests and you aren't confident that you can create those tests then I'd bring it up with management. Maybe they'll say that changes in this functionality will be very rare after this small change and that it's very well tested manually and by customers - then that's it. Not all code has to be made concise and elegant, it's better to focus your effort on the code that regularly needs changing. However, in this case I'd ask management to consider not changing it at all, or make sure it will be very well tested manually after your changes).

Re: Ask HN: How do you deal with 2000 line functions?

#45
Michael Feathers' book, Working Effectively with Legacy Code, is highly recommended. In that book he explains that you can choose between two approaches: Change and pray, or Cover and modify. Then he provides dozens of different strategies to "cover" the existing legacy codes before you make the changes.

Re: Ask HN: How do you deal with 2000 line functions?

#46

1. Unit tests. Otherwise modifying old code is full of potentially unforeseen landmines. 2. Read the function a few times to get a sense of what it's doing. 3. Break the function into blocks of statements that are performing a related task. 4. Factor those out into smaller functions. 5. Recursively repeat 3-5 until you're satisfied with the new functions' line count. > Should I tell my manager that the function needs…

There's no way to add unit tests to a multi-thousand line method. There's almost no way something that long was written in a testable manner.

You can probably add some tests around the inputs/outputs, depending on the structure. For example you might have to check the database before/after and other things like that. But it won't be "unit" tests in the conventional sense. More like Integration tests, because something that long should not only be multiple methods, but multiple classes.

Re: Ask HN: How do you deal with 2000 line functions?

#47
post #45

Michael Feathers' book, Working Effectively with Legacy Code, is highly recommended. In that book he explains that you can choose between two approaches: Change and pray, or Cover and modify. Then he provides dozens of different strategies to "cover" the existing legacy codes before you make the changes.

+1 on the Feathers book recommendation.

The good news is that many, many, many people have been here before you. While you may have a lot of work ahead, you can do it safely and in an orderly and safe fashion. (And with something as butt-ugly as that sounds, that's the only way I'd do it)

Re: Ask HN: How do you deal with 2000 line functions?

#48
post #21

Don't tell you manager anything, just do it. If someone tells you to add functionality to a 2000 line function, it takes extra time. If you want the company to benefit a little bit more from the time you spend on grokking it (by saving the next poor soul some time) by splitting it up. Go to the part that you suspect you need to modify, identify a block of code that together forms something you can give a name, i.e. "…

If you write C/C++ then you probably need fast code. Function calls - unless inlined - have a small cost. The cost is really rather small (think memory writes) and can be negligible depending on where the values are stored.

That is of course rarely the reason. From what I've experienced it's usually that the developer is uncomfortable with abstraction (at least that was my reason many moons ago).

Re: Ask HN: How do you deal with 2000 line functions?

#49
post #4

You test the shit out of it, then re-write it ensuring tests pass, then add your new code. It's probably easier to do that than to muck around in the 2000-line version hoping you don't screw something else up.

The other trick once you have tests is to change the code to be easier to work with without changing its behavior. Prefer doing this in small steps that you can be confident about. Once the code is in a form amenable to change, which usually means a change in one place doesn't have non-obvious behavior in other places, bugfixes can be applied.

Re: Ask HN: How do you deal with 2000 line functions?

#50
Depends, but very likely. There may be cases were there is practically no way around a 2000 line function, one example would be a something like a very long switch-case statement, were the logic is very simple, but there are a lot of cases to cover. For example something equivalent to (python pseudo code)

     dict[ keyword](args)
were dict is a large dictionary containing function objects. In that case the dictionary approach has the advantage of separating the logic from the clutter, but it is possible to work with 2000 lines of

     case something:
         foo();
         break;
However if it is not such a case, then you are in trouble. Thing is, management does not like to be told that the code is a steaming pile of shit, and management is especially unhappy if you tell them that you are going to spend a few month on accomplishing absolutely nothing. From their perspective refactoring is accomplishing nothing: the functionality is there, it works and they do not care about the gory details. So you need to convince your manager that refactoring is a good idea, which just goes against every basic assumption of his job. So think about the actual problems you have with the code, and what the company gains by refactoring it. (Easier extensibility, less risk of bugs and faster turn around if a bug occurs.) Then make sure that you convince your manager that refactoring is the right thing to do. ( Ideally you should enlist your coworkers for that, if they know the kinds of problems.)

Speaking a bit more generally, this is part of why technical dept happens. Selling refactoring is hard, so everybody tries to tip-toe around the 2000 line gorilla until some unhappy soul (read someone else) can no longer avoid to wrestle with it.

Post reply on HN