01:10 - Bryan Helmkamp Introduction
02:54 - Code Metrics
04:24 - Why should you be looking at metrics?
09:14 - Ruby Rogues Issues with Metrics
13:27 - David Chelimsky's RubyConf Talk
14:18 - Duplication in Controllers
17:03 - Code Complexity vs Duplication
19:17 - Aggregated Metric Examples
20:58 - Roodi
23:06 - Composition / Composed Method Pattern
26:00 - Too Many Methods / Instance Variables?
26:45 - Code Smell
28:35 - Programming Style in Metrics
31:27 - Tools for Detecting Immutability Violations
32:00 - Tracking Code Metrics
35:11 - Other Metrics
37:20 - Measuring Test Complexity
37:56 - Test Coverage Tools
38:51 - Metrics Fitting Into Agile Team Process
42:00 - Downside of Metrics on a Team
45:12 - Organizational Uptake of Metrics
48:00 - Metrics and Money
50:34 - Behavioral Metrics
53:02 - Custom or Idiosyncratic Metrics for Teams
DAVID: Chuck we wanted to know, did Obi-Wan call and tell you to take the trash out?
JAMES: (That's awesome.)
DAVID: That's got to be an abuse of the force.
CHUCK: (Oh man.)
DAVID: Imagine if Obi-Wan is a force ghost, just like, Luke feed my cat!
AVDI: Luke, can you read me peanuts from this latest paper.
JOSH: As a ghost I cannot turn the pages.
DAVID: I am bored what you are doing?
CHUCK: Hey everybody. Welcome to episode 41 of the Ruby Rogues Podcast. This week on our panel, we have against the rogue, its Bryan Helmkamp!
BRYAN: Hi guys.
CHUCK: Bryan, you want to introduce yourself?
BRYAN: Sure. So, very happy to be on the show today, my name is Bryan Helmkamp. I work on a number of things in the Ruby community. I’ve done some open source stuff. Most recently, I'm working on a called Code Climate (which we will talk about in a little bit). But I also help out in the New York Ruby community, organizing the NRCrb meet-ups and GoRuCo.
CHUCK: GoRuCo, not to be confused with go GoRuCo right?
BRYAN: Not to be confused with go GoRuCo. We had the name first, which I think Josh will admit to.
BRYAN: We authorized the licensing of the Go GoRuCo name.
DAVID: Is Go GoRuCo based basically the Lady Gaga of GoRuCo?
BRYAN: I think that's apt, yes.
CHUCK: All right, also in our panel we have Avdi Grimm.
AVDI: Good morning.
CHUCK: We also have David Brady.
DAVID: Estás usando este software de traducción de forma incorrecta. Por favor consulta el manual!
CHUCK: We also have James Edward Gray.
JAMES: Wait I am confused.
DAVID: I wanted to see how long it would go.
JOSH: David you do a great Steven *** impersonation.
DAVID: Thank you.
CHUCK: And finally we have Josh Susser. (I say finally and then I have to introduce myself too. Anyway,)
JOSH: I refuse to be finally.
JAMES: I do not think that word means, what you think it means.
JOSH: Oh, we are going to go down this road again are we?
DAVID: I think the word you're looking for here is “penultimate”.
CHUCK: Yeah, and finally, I'm Charles Max wood from TEACHMETOCODE.COM. So, this week we are talking about code metrics.
CHUCK: So who is going to get us started?
JOSH: Talking about code metrics, hey Bryan how about a definition?
JAMES: He loves doing that.
BRYAN: You bring the gust on and then team it right up.
CHUCK: Stand right here get the bus, beep, beep.
BRYAN: So, software metrics are, you know, data that can be derived from the code, making up a code base or an application and there sort of broad interpretations of that. And more specifically, you know, I think a lot of the stuff that we are going to spend some time talking about today is what you would call “Static Analysis”. And that means, you know, metrics that you can drive without having to actually execute the code in question. There are other metrics like one that, a lot of people would be familiar with, like Code Coverage which actually requires running the code. So we'll talk probably, I would imagine about both static analysis and something to turn out static analysis.
JAMES: So I'll confess that I am like a “code-metric idiot” and so I can offend even more people this episode than I did last, which should be great. I guess I don’t often find myself wishing for code metrics. So I thought I'd give you a chance, Bryan, to tell me why that is dumb opinion and why should I be looking at them more often than I do.
DAVID: Oh man, James Edward Gray asking you to tell him he’s dumb.
JAMES: No I'm serious.
CHUCK: (I dare you.)
BRYAN: Well, I am not going to do that. But you know, I think there is value in looking at the work that you are producing from a pan of detail, in different angle, than the way you’re usually processing it. So if you are, you know, a professional tennis player or golfer, you know, you got your game and you know you are still after a match. You’re going to look at whole other details about how you played under different scenarios. And I think for the experienced developer, you know, code metrics can serve that role, just to, kind of like, another way to maybe uncover some new ways of thinking about things or new ways to solve problems that, might have been outside your normal thinking. I think another big factor is, if you're working with teams. So, if you got a team, then I think the most of valuable part of software metrics can be the discussion that it prompts. Basically, it’s not that any sort of automated metric on a code base can replace the judgment of a good developer, but you know, sort of, inspiring conversations about, you know, is there a different way that we can do this? Is our new approach working out? Are we on track for the goals that we have set for ourselves as a team? I think that can really be helpful use.
DAVID: Do you think it's wise to set a complexity goal for a team?
BRYAN: I wouldn't think it's wise to set a specific goal for any specific metric for a team, but I think you need to look at things, sort of “combined” and take a view of the full picture. And in that regard, there is some ways to do that but, if you can say, alright guys, you know, at this point we have a few classes that we know are problematic and, you know, I think we can get on the path to where we sort of fix those up in the way that we are not scared of them anymore over the course of the next few months and in the meantime, not introduce any new issues at start to sort of, you know, accumulate. So I think it's a little higher level than saying, you don't want to get into a place where you are optimizing for a number, because that's going to cause you to make, in some cases, decisions which are poorer than you know you would make without the metric just cause there are so many things that need to be reconciled when you are working on a piece of code in the real world. But I think you can set high-level goals.
CHUCK: Yeah, we don't see that in the real-world, like gaming things for unemployment numbers and what have you. Anyway ---
DAVID: I think that is just a brilliant answer Bryan. I have worked on teams where, we have said we would get our code complexity to this number and we would get, even more common, right, as you see we will get our test coverage C0 coverage or our C1 coverage. We would get it to this percentage and invariably, once you say, the number is the only way we are keeping score, you'll get some idiot who will sit down and he will write a single test case, that loads every file in the project, makes no assertions in the code, but it loads everything and then assert true and congratulations, we now have 100% C0 coverage! And this guy gets the employee of the month bonus and he’s actually made things worse. He's done absolutely nothing good. I liked your answer of basically saying, and I'm actually going to put words in your mouth because I'm going to extend what you said here.
BRYAN: (Go for it.)
DAVID: It sounds like a good idea, what you're saying is a good idea, is to review this complexity metrics frequently with that team and say what is this telling us, especially in conjunction with other pain spots or other areas that we know.
BRYAN: Yup, I think I'm happy with those words being put in my mouth.
CHUCK: I really like the idea too of not just talking about, you know, some of the symptoms of what we are doing, but the way that it helps us identify some of the problem areas, which you have kind of implied in what you said.
JAMES: Yeah I think I'm really comfortable with it as like conversations starters. I guess, one of my concerns (did I mention I'm a hostile witness this time), one of my concerns is that, like, I don't know, I really feel like I have always filter it through a lens of, you know, human common sense in this. Like for example, I gave a link, I was playing Code Climate this morning and I gave a link to the rogues this morning and at one point it told me that, it flagged one of these classes of mine as red for duplication. And its mailer with two methods in it, and even the instance variable assignment is different and about the only duplication is that, I called to rip mail you know and give get the To: in the subject which Rails pretty much requires me to do, you know. And then I duplicated one constant in the subject I guess, so, I mean but still, there is still a lot in there that is not duplicated like, I was really surprised that it take that flag and I hope that any human would look at that and say, no that is okay. I mean like the method or--
AVDI: But the parse tree probably, is probably a duplicate.
BRYAN: That's right.
AVDI: I happen to know how that tool works and the parse tree is probably a duplicate. And actually it's surprising the duplication that, that tool can bring up, which you just like never thought about before. Because you’ll have a piece of code that’s exactly like you said where the variable names are different, but the structure of the code is exactly the same.
BRYAN: Yup and we should give credit to the tool that you are referring to Avdi is “Flay” in this case. Which is a very useful tool, runs in the command line, it's created by the good folks out in SeattleRB and it looks at these parts of the code looks at the parse trees and compares them. And if they are identical, then you know, if you look at the code and say, yeah it's exactly the same code, (maybe it just find that just a little bit differently) but in this case, it's actually sort of ignoring the specific identifiers and the specific strings and just looking at the structure. So it's okay. It's an instance variable assignment, followed by a method call, with the hash argument and the hash arguments followed the structure. So that is kind of what going on there. James, I totally agree with you that in this case, you know, I think the right judgment is, this code is fine, it should be left alone. And that's where, sort of, the using metrics for good and not evil part comes in. And I’ve seen this go the wrong way and it pains me deeply. You know I had one case where, there were couple controllers and just by the nature of, you know, if you have very simple Rails RESTful controllers that are following conventions. You know, it actually, the parse tree for almost the entire inner body of those controllers that we use to start when we are not doing anything fancy, could be the same. And a tool like Flay, for Code Climate which actually builds on a Flay among other things, will say, okay, these controllers look like they are actually the same but, the logical, or one logical conclusion that is okay, you know what, I need to bring out here is a base class and some meta programming and bring out like they chainsaws to make sure that we are removing the duplication there. But I think that, that's why I get into using the word, “chafe” as the extension of “dry”. You can dry things up to the point of being chafed. And that is not what a, not usually a good thing. So you got to interpret the results.
JOSH: So basically, the old chestnut about premature operation applies.
BRYAN: Yeah, in some form I think.
DAVID: Well, or, reductio absurdium right? Or absurdum, that you can’t take—
CHUCK: Did you take that from harry Potter?
DAVID: Yeah it’s a spell. Yeah, its reduction absurdium not reductio absurdum. But to take something to its logical conclusion, to the point that it becomes ridiculous, right, I mean you can, if you, basically if you remove all duplication from your program, you have just Bzipped it.
BRYAN: And I think there is a good presentation on this (that some of you may have caught). Its David Chelimsky, he’s presenting at RubyConf. The presentation is called “Maintaining Balance while Reducing Duplication”. And it sort of overriding point was, the dry principles sort of expanded actually means, every piece of knowledge must have a single, unambiguous, authoritative representation within a system. It doesn’t just mean, don’t repeat yourself as a simplification. So it goes through a great example, where as some code to generate URLs and at start it looks like a pretty sane Ruby code, but it does have if you take a fine grain look at it, some duplicated parts, you go to all this sorts of contortion, removing more and more duplication. And so eventually it’s just like a whole bunch off, you know one letter constants instead of all being mapped together and completely incomprehensible. So I definitely recommend that presentation of sort of thinking through this ideas.
CHUCK: Alright, one thing I wanted to point out was again with the duplication. I ran it on some code been working on here, there and I happened to use Rails generate Scaffold a couple of times and it picked up the duplication there as well which I thought was interesting. And it kind of made me think, Okay, so should I not be using scaffold? Or is this really okay? Or you know, is there another solution that I should be thinking about? And it really kind of start, I guess, started that conversation with myself.
BRYAN: Yea it sounds like it’s very similar to, you know, the case that I have seen before where, controllers sort of composed this duplication question very acutely. And I'm not sure if there is an answer, I think it’s a question that everyone needs to be re-evaluating, as they add more and more of these things. You know, why is it seemed duplicated? Is it really a problem? Because it seems like, if I am fixing a bug here, I'm going to fix a bug there, maybe, maybe not. Sorry Josh, I think you were going to say something.
JOSH: Yeah I think this comes back to what I said about premature optimization. If you're optimizing in to your reduced duplication in your code, you can do that, but the point of say, scaffolding, isn’t to reduce duplication and to have one thing that will be really simple and compact. It’s to give you a starting point to branch out and change things. So, it’s actually kind of stupid to think about reducing the duplication on your scaffolding because, you know, the down side of drying things up, is that, you have now forced this two things to be the same and they can’t go into different directions as easily. So, yeah, you need to focus on that stuff on the right time. I don't know if I am making sense here I’ve only had one cup of coffee.
DAVID: I think there is also a good argument to be made like the entire notion of a framework is, I mean like, you sit down with Rails and you know that, you know, your models are apt models, your controllers are in apt controllers, your views are in apt views, and in a way that is duplication. Its duplication of a mental model, that you have in your head and what the file system is on disc. And if you open up a controller and it’s got an index method and a view method and a delete method and a create method and a new method, that's duplication but its. I hope I'm not repeating what Josh just said but I mean it’s good duplication. You’re basically saying, this is -- oh God I duplicating what Josh said isn’t I?
DAVID: I'll just stop talking now I have a Flay complexity of 28 it’s, yeah, sorry.
CHUCK: So that brings up another thing that we've kind of talked about as far as code metrics goes is complexity versus duplication. And I've seen it measured in a lot of different ways. I mean, I’ve seen it measured by just the cyclomatic complexity, which is the number of branches. I've seen complexity where it's the number of assignments, the number of branches or the number of conditions and the number of branches and all these kinds of stuff. Which ones do you guys generally use and why?
JAMES: Well just looking at Code Climate here I have a number of projects open and I noticed, in the listing itself across the top, it has complexity, I assume that is cyclomatic complexity, right?
BRYAN: Well actually that's the complexity number that, it's basically Flogs score. So Flog is a companion to Flay and does this sort of complexity analysis. At its core, it’s closest to what you would call an ABC metric, which means a metric that combines scores for Assignments, Branches and Conditions and those kind of specific formula for working that. But Flog is actually, sort of a modification of the ABCD metric done by Ryan Davis, where it counts that stuff and it also is Ruby aware. So it’s going to penalize you if you are using eval much heavier than it’s going to penalize you for other things. So it's will, not like your meta-programming also, so all is sort of worked into this metric which is listed as complexity and you can get it out of the Flog tool on the command line as well.
JAMES: So then the next column is just “M” which I think is methods and then “C” over “M”, so I assume that the ratio of complexity to methods right?
BRYAN: That's right.
JAMES: And then duplication is the other metric that are displayed there. Now of course when you click on to something you get an even more detailed breakdown. But I was just saying that, as a high level, that's like Code Climate matrix.
BRYAN: Yeah I like the aggregated metric. You can go with a something like a simple complexity, cyclomatic complexity and there is a tool called “Saikuro” (I'm not sure if I'm pronouncing that correctly) that does that for Ruby. And it's just straight up what's the cyclomatic complexity of this different code unit. But because there’s so much other stuff that can be going on in Ruby code, rather than looking at that and needing to sort of, factor in those other things that in the form of the other metrics, I like the aggregated view that Flog scores give you. And you can sort of have this internal rubric in your head around, okay, you know, everyone has a different comfort levels with how big a method can be and I think this is something that I think is fascinating. Just like the different worldviews on like what is a complex method and you definitely have cases where one person’s complex method is another person’s, you know, beautiful beautifully factored method and you can sort of whatever it is, you can create your own internal rubric for whatever reasonable Flog is for your project.
CHUCK: I think what's interesting point too is to, is that, a lot of people try and come and they try and say, well you should only have a cyclomatic complexity of “X” and you should only have, you know, another score metric of “Y”. And really what it comes down to is depending on the project, the problem and the team or person that is working on it, you know, those numbers can definitely change. And so I would caution the listener to take any metrics that people are giving you as far as where you should be with a certain grain of salt, and just make sure that you understand how that fits with what you are working on.
DAVID: Bryan has you used Roodi?
BRYAN: I have used it a little bit but not consistently.
DAVID: My experience with that is that it really drives up against what Chuck was just saying. Is that Roodi a great tool, but it's very opinionated. It's almost like- it's almost like metric driven development. It’s meant to be run against your code repeatedly and it has opinions. It will come back and say it will tell you; this method is more than 25 lines long. FAIL. If it’s too long, shorten it. And that kind of gets up in my grill a little bit, like you know what I'm smarter than you tool. I'm going to go ahead and do code my own way. But I also find that if you, that the motivation to have very short methods, in some styles of programming, for lack of a better word, we'll call them “bad styles”, long methods are great, there is a reason for them. And if you're doing object oriented programming badly, if you're not really on board with like, software decomposition where you start at a high level and break things down and break things down and break things down. But if you're starting at that composition level and you're starting with the tiny little bricks and building your way up, it is very easy to create these long methods especially when you're trying to compose things together. And if you just blindly adhere to these 25 methods, you end up with really stupid methods. You end up kind of cutting the meat, not between the fat and the meat but, you know, you cut crossways and (I’m making a really bad metaphor out of this), I think making metaphor hamburger but, the point is, is that with, Roodi, I found that doing software composition, it led me to a bad design, almost invariably. I'm curious to know, is (I haven't tried this with software decomposition with the top-down approach) are you, have you used any of this is like a method of driving development and succeeded in having it yield and drive a good design?
BRYAN: Yes I just wanna first I think there's a really good word in there that I wanna call out and plug a pattern which you used the word “composition” a few times David. And I think when you're talking about the complexity of methods, in sort of different people preferences, you really need to think about the composed method patterns, which is, it goes back to this small thought Smalltalk best practice patterns and the key outline in composed method is not about its size, it is about, is all the code within the method in the same level of abstraction?
BRYAN: So, you know, you sort of want this flow where you have these higher level methods, where you are not going back and forth between sort of very specific details and high-level concepts, it’s sort of, breaks down in these compositions. So I just want to plug the composed method there.
JOSH: Yes so that's a great segue to my question which is, when I look at these metrics and I see, oh hey there is some duplication on this file, it's just sort of throwing a red flag on it. But there is no real suggestion about what’s the solution to it. And of course you know I'm a highly skilled software engineer, so I can often figure that out for myself. But isn't that kind of the point of an automated tool, to lead you in the direction to improving the situation? (Or maybe it's not). But what I'm wondering is, are there metrics that are particularly useful for-- I actually have to Kent’s book in my hand and I was looking through this, oh what are the kinds of refactoring that this book is suggesting, and are there ways to do the metrics that will say, oh well, you know, this code really needs some sort, you know, delegation applied to it, because or maybe you need to do less inheritance and more composition. Have you seen anything with metrics that can be that high level enough to be able to be useful there?
BRYAN: Well, I think that it's a very much a trade-off and David got to this a little a bit earlier, that you have these metrics that you can apply across the code base, things that are true of any system, you know, like complexity, right, what's the total complexity of the class, how do you measure that or methods. And then you can, go sort of, into details and that sounds a bit more like what Roodi does where it sort of tries to figure out, okay, it looks like you've got a you know, an object design issue here, where you just have maybe too many methods in this class or you know, too many instance variables, I guess is one that's probably a good example. And so there is a tension kind of between how good a tool can be and the more detailed it this, the harder it is to make good recommendations, versus sort of saying that a higher-level and the programmer sort of needs to apply their judgment to figure out how to resolve the things. And you know I think you don't want to get too far into the weeds of sort of looking for, I don’t think it's truly possible for automated tool to go too far down the road of making design recommendations. One thing I like to point out is, a smell, a “Code Smell”, and I'm going to use that term on the podcast here, but you know if you think about what the cold smell is, it's not that it's not a specific problem in of itself, it is a pointer that says, maybe there's a something going on here. You know, I guess a smell is not necessary equivalent to a pile of poop.
JOSH: Unless you're working in David Brady’s office.
DAVID: It's still not true; a code smell is not necessarily equivalent to one pile of poop.
CHUCK: So one thing that I like about the code smell paradigm is not just that, it helps you identify problem areas (and not everything that looks like a code smell is a problem) but you know, the general case, it is generally true. But the thing I really like about it is that, it's basically a way of recognizing a place where you can use a pattern to make your code better. And that is a very, very handy thing. And there's a tool, it was written by Kevin Rutherford (I’m trying to remember what it’s called), that identifies code smells in your Ruby code.
BRIAN: Kevin’s *** is Reek.
CHUCK: Yeah, it’s Reek and it will go in and it will identify different code smells in your code. And you know it's pretty handy. in general, I like these tools too because most of them, they give you some read out that, at a glance you can kind of look through it and easily either identify a problem area or dismiss something its saying is a problem area, you know, without spending too much time. Because we want to spend most of our time coding, we don’t want to spend a ton of our time sitting around the staring at these read outs.
JOSH: Hey Bryan I’ve got a question about programming styles and metrics. You know, Ruby is very flexible, there are ways to use it that are very strict object oriented, there’s people who use it in a very functional way. People even write procedural code in it. Do you find it--
BRYAN: A lot of people write procedural codes in it without realizing it.
JOSH: Well yeah.
JAMES: Just to be clear though, Josh thinks the functional people are wrong. I'm just saying that because I got more hate mail than you did last week and try and--.
JOSH: You know, everybody jokes about hate mail. I never get hate mail. I've never gotten a single piece of hate mail.
DAVID: You're asking for it now.
CHUCK: I was talking about Emacs last week and I didn't get any hate mail.
JAMES: I obviously addressed it incorrectly because I got it.
JOSH: Back to my point. So there are different styles of programming. Are there different ways of analysing code that are more useful or less useful, depending on differences in programming style?
BRYAN: That’s a really good question. I think that, you know the tools that we have in the Ruby ecosystem right now are largely of the object oriented paradigm. And I haven’t thought very much about what that would look like in a functional paradigm to for example. So Ithink that will be an interesting area to explore. I the wonder what the languages that are more purely functional do if they have any tools like this. I haven't seen any but, I also am just not as familiar with these ecosystems.
JOSH: I can say that one of the metrics in an object oriented world, might geared towards the law of Demeter or Demeter, I've really have no idea how to pronounce that word anymore. Ok so LOD, there might be a metric that says, you are calling methods, you're sending messages to an object that isn’t one of your arguments or one of your own values and that's a Demeter violation. But in a functional language you totally wanna be chaining call after call after call.
AVDI: Disclaimer, not all chaining is a Demeter violation.
JOSH: Thank you. But, anyway, those are distinct differences in programming style, one of which is appropriate to an object oriented style and the other one for functional. And you metrics might influenced by that.
JAMES: Sure then functional language you can have some something that warns you that you are accessing a global variable and that thus you are not writing a functional style.
DAVID: That is a very good point. Are there tools out there for like detecting like immutability violations and that sort of thing, that are not standard like standard code smells?
AVDI: It’s called Pascal
BRYAN: Yeah that's actually done at the language layer. Is just one of those concurrency problems which I haven't seen a perfect solution for. How do you avoid accidental mutable state? You really need to be down in a lower level to do that I think.
JAMES: Alright so let me try to redirect a little here, so if I want to get into tracking my code metrics and stuff like how do you guys go about that? Like you're just working on you know a little project with yourself or whatever how do you get into that habit of taking those numbers all the time. Do you like set up a commit hook on your read post so that every time you commit it’s at the blog number or what do you guys do?
BRYAN: James that's a beautiful TF for Code Climate.
JAMES: But that wasn't my intention but yeah you're right, go with it.
BRYAN: Okay so this is what the reason why I wrote Code Climate. And you know I seen a lot of teams get started with code metrics and they sort of fall off the horse, because of something that they need to implement either on their CI server or their local development environment. They get started with it and that something, some new version of, some new jam is released three months later and it breaks and you know the team is really busy and there's not enough to fix it. So with Code Climate, you can just connect it to your get repository on GitHub for a public key. It will put in your code, it will run. There’s a commit hook that's through GitHub’s push up so it will run on every command. Also it will actually shoot out e-mails as the code quality is changing. So you don't have to do anything, except just check your inbox and it will let you know when there are things to look at.
CHUCK: Okay I got a question. When it changes is that climate change?
DAVID: Yes but it’s not androgenic.
CHUCK: Sure it is, people are changing it. They change the code, they change the climate.
DAVID: No the code ecosystem is so big, there’s no possible way humans could impact it.
CHUCK: Oh, I see.
CHUCK: Alright, sorry for bad joke.
JOSH: Crickets, crickets, crickets. That's awesome.
CHUCK: But yeah, I really like that idea. one thing that we did when I was in public engines, I was in charge of the CI server and so one of the jobs that I set up on Hudson was basically to run metric fu and I don't know if anyone was really looking at, it but yeah it will incrementally save off the changes and stuff and then you can see the output and it was really kind of handy to be able to. Because every time you push it, it picks it up, so, yeah same kind of thing.
JAMES: So there is a play-by-play episode on Peepcode with Zed Shaw I believe and in it he kind of recreates one of the tools. He used at one period of time, and tried to religiously like in every commit he generated a bunch of stacks as I commit hub I think I. And some of the stacks he did in there are things that we typically do not look at with all these tool metrics. Like for example, I know he was tracking bugs and I can't remember exactly how he do that if he ran the test read and check to see if they caught something he missed or whatever I'm just saying are there other metrics we should be looking at too and in addition to just Flays, you know, like the complexity of methods and stuff like that, any thoughts on that?
CHUCK: That code is self-debugging that's how he does it.
BRYAN: Yeah so I think the one take away in terms of how people set things up that works well, it seems like everything else with developer tools automation it is a big key. So you know, the CI thing works well, local post commit works well. As far as you know other metrics, I think there's a project out there called “Limited Red” which I think is kind of interesting. Have any of you guys heard this? It's by Joseph Wilk of Cucumber Frame. I'm not sure exactly where he is at with it but, the idea is it keeps track of, for each Cucumber feature file (this same idea could apply to any test framework), which tests are most likely to fail. so that could be an indicator of a lot of things to be just it could be just a portal test, it could be that that area of the code has too many responsibilities and so it can give you that information. And also as a feedback loop, I believe it will optimize the order of your test run so that it puts the one which are which most likely to fail first to try and give you quicker feedback. So that just came to my mind in terms of you know, pretty different from the type of metrics we've been talking about previously and it's not static analysis at that point because you know you're using the runtime result of the tests. But I think the idea of keeping track of test level data how fast is this test over time is really interesting, because when you end up a slow test sweep the question is always well, when did it get slow and it wasn't in some day. You know but there are probably days where somebody introduces some, before set up code that maybe makes every test a little bit slower and plotting that out will be I think will be really, really interesting.
JAMES: So Bryan, that actually led me to another question. I noticed that in analysis Cold Climate did of my code today, it did not say anything about my test. Do we not measure complexity and stuff in test or why is that?
CHUCK: Test or code?
BRYAN: No, it’s a good question. Code Climate doesn’t do anything with test right now, but that is definitely on the horizon correlating the breakdown of the test information. At least what you can do with a static analysis, initially, with the information about the code and the test so you’ve hit a roadmap feature on the head there.
CHUCK: I used to run code coverage tools in Ruby 1.8 and haven’t had a lot of luck running any of the tools in Ruby 1.9. I'm curious what you guys are actually using.
JOSH: The two that I have seen are Simple Cov and Cover Me. Although I haven't actually gotten those up and working and automated on the 1.9 project yet
DAVID: I’ve had some good lock luck with Simple Cov it gets its eyes crossed a little bit if you do anything complicated. But it's simple to set up and use.
CHUCK: Right you use that with guard?
DAVID: Yeah. Or you can use it with just put it in your RSpec suite tells it to start coverage when you run your RSpec suite.
JAMES: Avdi what was your question?
AVDI: Oh, we’ve some about the personal process with regard to responding to metrics. I'm just curious Bryan, how you see metrics fitting into the typical agile software team approach and you know like how does that feed into the iteration or planning or aspect of-- how do concretely apply that in your software team process?
BRYAN: That's a good question. I think different teams have different processes obviously. You know some teams will do the GitHub style sort of poll request system. And in that case I think that that's a good time to bring metrics into the conversation. For teams that are doing sort of a more, sort of extreme programming approach, whether they are doing pairing, no sort of formal code reviews which are sort of pairing then master then out the door, then I think, retrospectives can be an interesting time to sort of bring these stuff up. Obviously you don’t want to be talking about a bunch of super detailed technical stuff when you have the whole team including non-technical folks in their butt. One thing I have dealt with is setting brown bag, brown bag launches where we would do kind of a group refactoring aided by metrics. So someone would say, hey, we have a good standing brown bag launch every few weeks and it will rotate around the team. Someone will be responsible for basically selecting a piece of code, not necessarily something that was even worked on recently. They can incorporate matrix in the conversation and the goal for the brown bag session was to actually finish a refactoring of that code, however small it needs to be, so that its green and can be shipped immediately. And then there were actually cases where we get to the point where we actually had something that was sort of green and ready to be shipped so we just threw it out, because the main benefit of that excursive I think was that the conversation around it with all the engineers sort of working through their own collective process about what's going on here, how do we want to approach this problem.
JAMES: I really love that idea of working on something and throwing it out. I do that frequently like I tell myself, oh, this method is terrible I can fix it in 10 seconds flat and then three hours later what I realize is that what I fixed was my understanding of how complicated that is. And that's totally it, once I’ve added that to my head it’s like okay I now understand watts going on here and I throwaway my aborted attempt to change it to something else. I think that is fine but what we can put in our heads. But my concern on the teams, (as the skeptical member on the show) is does it ever become a problem where you need to take certain steps to keep the code metrics from being like a finger that somebody can point, oh look at that class that's complex or something like that. It seems like that will be a downside to using on a team.
BRYAN: Yeah I think that, to some extent it can be okay to look at a piece of code and say, you know, oh look at this, that you know, this is a problem area that we need to improve. But you know, you definitely wanna keep the focus on the work and not on the people. And that's just one of those, like very deep and sprawling team trust issues. And you know, code can be personal in some cases if you feel like it’s a personal work product. So, for the case of the refactoring brown bags, that is one of the reasons why we would usually not picked something that was worked on recently. We just go back in to the archives and pull out some class that maybe hasn't been touched in a while. It serves the same purpose for the conversation but by that point people have less of a sort of ownership mentality of it. People will sort of seen it causes problem and everyone’s got sort of a collective sense that this is something that needs to be addressed. And then it’s not about pulling out the, one of the most troublingly named commands in the software development ecosystem which is the old “get blame” it’s about looking where is it and where you wanna take it.
DAVID: I'm having a huge déjà vu moment because I'm realizing we had this exact same conversation 10 years ago, only we were talking about unit tests. What you do you do when you a tests fail you know, do you go track down the person who did it beat them?
AVDI: So I’ve kind of a holy grail question, how close are we to being able to say, in a retrospective or something, this area of technical debt, this known area of messy code caused N number, N hours of delay in this last sprint.
CHUCK: Ooh, that will be really interesting.
DAVID: There are people working on it. There is a tool called “Sonar” that I talked about in agile roots in 2009 or 2010. And it’s literally, it's a terrifying tool because it basically takes your failing specs and it takes your regression specs and any bugs you have to go back and fix. And it actually calculate metrics, turns them into dollars and then it prepares a report that you can take to the executive VP and say, technical debt cost you this much money this month. It’s a terrifying tool yeah. It’s not perfect obviously or it would be sweeping the storm or you know sweeping the—it’s been out for a couple of years and it's still out there. But it hasn’t won a clear victory but it's exciting to me to see a tool like that. It has begun to exist.
AVDI: Well, it's a big deal.
CHUCK: The interesting thing to me there is not just that but then you can get them on board with changing the process.
AVDI: That’s exactly it. It is you know, the problem with, that I've seen with uptake organizational uptake of metrics thus far is it's, you know in the end, it’s it can still be hard to justify them. To make it clear why they are important and it's connected to this issue of it's still hard to quantify, you know, everybody all the programmers whine about this area, of you know, of un-refurbished code that you know, the old team did or something. You know, and it talked about how it's slowing them down, but we have yet to have to find a way to quantify that and as a result it’s like, well, you know, just make do as well as it as well as you can, and try to work smart and don’t let it slow you down too much. And it's sort of parietal need to have a way to say, look, this has really, genuinely costing us money.
DAVID: That notion of don’t let us slow you down too much is ,it's like an emotional shortcut that will guarantee that your technical debt will up and slow you down even more.
JOSH: We actually came up with a real metric for that on one project. Where we were not enough DataMapper, too bad because it's moved on from this point where you are using the 0.9 version of DataMapper which has some real issues. And we actually measured over the course of a month or so that it was costing us two days a week, to deal with the overhead of all of the problems we have working with this old version of DataMapper. And the team didn't want to upgrade because there was so much effort involved in doing the upgrade and either moving to the new DataMapper or to Active Record. And I guess the upgrade for DataMapper is pretty expensive. So we are thinking, well if we are going to do all that work maybe we’ll just go to Active Record. But anyway that's not here nor there, but the point was we were able to actually look at how much time we spent during the week and it was pretty consistent for a month, we spent 40% of our time working around issues with DataMapper.
AVDI: How did you track that?
JOSH: We just looked at all the time we were spending.
AVDI: Were you keeping logs of like what area of the code you are working in or, I'm just curious. Or did you just sort of have a sense of it?
JOSH: Well you know, we could look at the stories that we worked on in tracker and so we can say okay what do we do this week and okay these are the stories and then really we just check in with our own memories of what we spend all the time on working on the story. So if we spend half of the week working on stories that were all business logic down in the modal layer and we felt like we spent almost all of our time fighting DataMapper, then okay, that was two days we spent on DataMapper.
DAVID: This is taking metrics to a place that that's really, really interesting to me because it's really, it’s taking it to the money place, where, you know, we are talking about metrics or we talking about where our technical debt is. And these metrics can maybe help you get a feel for, should we rip this out and rewrite it? Can we afford to go six months with no new features? Should we just try to stay with what we have and pay off the technical debt?
JOSH: Putting a dollar value on, you know, the payment plan for your technical debt is really useful for a project. We went to the client and we said here's how much you're spending each week.
DAVID: I would also on a time value. Because if you come to the client you can say we can fix all the technical debt in this project but it's going to take nine months. The VP of the company will go, I cannot tell my customers that they can have no features, no new features, for nine months! So you know, it’s really where the check book hits the road somewhere.
JOSH: If you don't know you cannot make evidence based on---
JAMES: Yes that's a great point. Like, I use metrics all the time not like this static code metrics we’ve been mostly talking about. But, for example in one of the projects I am working on right now, we are using a certain API and were considering migrating to a different API and there's a lot of trade-offs involved with that. So we’ve gathered metrics basically by going through and looking at the searches we're doing during the day, using that one API and then when we play those, in the side, separate task, against that API and how we will do the same thing versus the other API and we compare the results we’re getting. You know are we getting more results, you know, less results and I how much times is that taking and stuff. And we have used that to show that basically, switching to this API effectively can almost slow web application down by a third, you know it’s kind of a big penalty. And so then we used that to put pressure on the API people, you know what, you know hey, we love to go today but you are going to have to make it faster, you know, that kind of thing. I think that is valuable.
CHUCK: (It is valuable.) One other thing that wanted to bring up was basically with these behavioural things. How many times you encounter something or you know how much time you spend on a particular problem. It’s important to track and I think we also, in a lot of cases, need to follow the general rule that I've seen in some of the agile methodologies, where when you see a problem you fix it. Now I get that some problems like upgrading DataMapper in Josh’s example are prohibitive just because it’s not, oh well, taking extra hour and fixing the problem. But in a lot of cases you can avoid a lot of the problems technical debt, you know, what have you, simply by paying attention and going this is fourth time I’ve worked around this issue with the user class so, I'm going to go in and am going to deal with this problem and you know then down the road you know, I'm going to save myself so many hours, because I don't have to spend a half hour or so working around it every time.
BRYAN: Yeah and so to expand up on that more. One of the phrases that you know I have worked in the development teams I've used and I really like is “proportional investment”. So something might be an issue is that causes you to have to spend time on it, but you don't want to sort of under react or overreact. And you know the over reaction is, “I ran into this issue with an Active Record upgrade and so we need to switch to DataMapper.” You know the under reaction is equally problematic which is, you know, “We've had this friction with an authentication library week to week and we haven't actually done any work to try to resolve it.” And maybe that work is actually working on library itself just cracking the hood and getting environment set up where you can make patched and submit them upstream. Maybe it’s looking at doing a spike, a time box spike to look at alternatives. It works the best when you have an incremental approach. So the DataMapper upgrade thing can be a problematic because you have to basically make this leap and those are the hardest changes to make. But I just also wanted to bring up that concept of proportional investment and you know, you can be on either side of the line and neither is where you wanna be.
JOSH: I know what you are going to say but a one asks one quick question first. So Bryan what about a custom metric for teams or idiosyncratic metrics? Have you seen much use of that? Do you think there is a place for that?
BRYAN: Yes, so if I understand what you are asking about, I think that I was just reading a post about this, this morning where there was a team, (it wasn’t a Ruby team) and what they did was they had a guy who would write some specific metrics related to specific changes that they were looking for so. So they were trying to get rid of the class. He would write a few lines of code which just keeps track of a number of references to that class and it was temporary. It was over the course of time from when they said, you know what, this thing needs to die to a point where it’s dead and then you throw it out. So I know that there are teams out there that have done it, that team in particular I don't think it was a Ruby team, but I think it's a really interesting idea, you know. I love the idea that if a team has a big-screen monitor next to their work area, and there's always that class or that library that is effectively deprecated but not yet removed. And there's, as you are bringing on new team members, it might take a long time to get over rid of this thing. Someone might not know that, were actually trying to get rid of “X”. So the idea of saying if there's a new reference to “X” that creeps in to the code base, I'm going to set off alarm bells, or I'm going to put that up on the monitor or where everyone can see it and then track towards zero. I think that is really interesting idea that there hasn't been a whole done with to make it easy in the Ruby community and but I love to see that and maybe that will be a feature.
JOSH: So that's interesting that's a goal directed metric.
JAMES: Yeah, I’d love that too.
JOSH: I could actually see a lot of places for being able to put it. Basically describe particular goals in terms of metrics and always has meter of how close you are to your goal.
BRYAN: As long as it’s pretty easy to pull out of the parse tree, then the amount of code to detect just a reference to a constant is quite well.
CHUCK: Alright and with that we will go to the picks.
JOSH: (Well done.)
CHUCK: Josh you can go first.
JOSH: Okay awesome since I was the blocker there. So, let’s see, I think we've talked about Travis CI on the show before (if we haven’t shame on us). But Travis CI is this big open source community-based project to do host of CI of open source projects and I think eventually they are going to be able to private projects that are aren't open source. But they wanted to raise some money so they created a “Love Travis CI” project to raise some money. I kicked in a few bucks towards that. I encourage everyone else to do that too because it’s just really great having this community resource out there that will run CI test to make sure that open source software will work against all the different versions of Ruby that are out there in a lot of different configurations of things. So it’s been pretty great having that and I encourage people to toss like 10 or 30 or whatever, however many bucks you can spare there. So that's one thing. And then the other is I was looking at some hardware issues with some of my Apple gadgets recently and I discovered this nice little program this application called “Mactracker”. They have a Mac desktop version and they have an iPhone version. And it’s basically a big database of all of the Apple products that you can ever have bought. And there are configurations and how much memory they support and what peripheral connectors they have. So it’s just really great for me to figure out which of my airport base station has the 5 GHz antenna build into them, that kind of thing. So, that's it for me.
CHUCK: Sounds good. James what are your picks?
JOSH: And who’s typing?
JAMES: Bryan that helps if you mute while you are typing.
CHUCK: Is that your pick?
JAMES: Is that my pick? Yes, the mute key in Skype. Okay, my pick this week is Ruby Trick Shots from Peter Cooper. He put up this new video in his ever-expanding empire of newsletters and cool Ruby stuff and all that, (just yesterday I think). And it’s just 24 random tricks that you can do with Ruby and it’s like a 30-minute video that you can watch through and they ranged from cool to scary don’t ever do that. You know kind of stuff which is great. I really enjoy stuff like this like I love the, mainly because the conversation that comes out of it and it’s almost impossible to look into things like these and not learn something along the way if you kind of dig in to how they work. For example there's a matching twitter account, where he's posting some other trick shots that other people have posted. And one of them is like a very simple hash bracket, hash sort bracket. And if you look in to how that works is actually kind of interesting, because it’s the harsh sort ends up sorting it into array of arrays. And hash brackets in Ruby 1.9 have actually been enhanced, so that they can understand an array of ways and take that to be key values and it ends up sorting your hash because hash is in Ruby 1.9 also one also sort of by insertion entry so. Anyways, I feel like if you peel back layers of stuff like that, you learn more about how the language works and why it’s cool and stuff like that. Another great source that came up in the conversation on Twitter yesterday, is this Gist from KS I guess. It’s just this great gist of an insane use of default arguments in Ruby that you can actually puzzle through and kind of figure out what's going on there. And things like that inspire confidence about how intelligently Ruby handles the arguments and things like that. Like for example we were talking about the default arguments on Twitter yesterday and I pointed out that you can actually yield as a default to another argument or access instance variables or things like that. So, it’s all just kind of, you know, along the same lines. And Peter pointed out that he got at least part of this idea for my Stupid Ruby Tricks article a long time ago, I think it’s from Crash right? (I can’t remember now) But, anyways, its blog post on ThoughtBot blog (which is kind of a lounge twister). This one in my opinion isn’t as stupid as the other say. Actually most of the things in here actually seem like good Ruby usage to me. (Take it with a grain of salt.)But I just enjoy this kind of digging deeper. Peter is preparing a book that has over a hundred of them in it. And he says, he is going to expand on them and you know, give more details about is this a good idea. What hash do you probably need to really do this and stuff like that. So I found all of that really interesting and I hope you do too so go play around with stupid Ruby constructs.
CHUCK: Alright, terrific. Avdi, what are your picks?
CHUCK: Alright, David what are your picks?
DAVID: Just one today, “Start-up Weekend “. I did not actually go. It was here in Utah last weekend or two weekends ago rather, no it was last weekend, I don’t know.
CHUCK: It was last weekend?
DAVID: It was last weekend. But, I was recovering from a really bad illness and I knew that if I went and did this, that I would just put myself back in the sickbed for another week, so I did not go, ut one of my friends went. Basically, I guess you can think of it like Rails Rumble only with a business model involved and required. And the friend of mine that went said that it's the most fun, (he’s in his 30s now) and he says it's the most wacky-fun, manic weekend of insanity that he’s had since anything he’s done since college. And I asked him, did you launch your start up? And he said, Yeah! and I said, Did you have a business model? Then he said, Yeah! And I said is it any good? And he said No. But that the experience of having gone and being surrounded by people who, instead of trying to set up trying to build a product, build a website, you actually have to build a product that has business model that actually serves like a functional business purpose that will satisfy somebody's need, that they will pay for. And he said that it was incredibly eye-opening for him. And I guess they are going to do them tri-annually so there will be another one in about four months. And I'm definitely going to go based on his recommendation. So, that's my pick STARTUPWEEKEND.ORG
BRYAN: I'm speaking.
CHUCK: Ah, sweet. So Bryan is speaking. And we also have a whole bunch of other people whose name you should recognize. I also recommend that you sign up for the workshops that are on Saturday. Some of them just look incredible, so I'm really excited about that. We got Gary Bernhardt (who was on last time) and several other people coming in for that so.
DAVID: I am so excited for the Hardware Workshop. If you guys, if you are coming and you haven’t signed up for the hardware workshop, sign up for this. You are actually going to be programming things you can touch and that will move around and react to your programming. How freaking cool is that?
CHUCK: Is that the one that JT is putting on?
DAVID: Yeah, JT is doing one. He’s basically going to set up Arduino with the board with the Ethernet shield on it and you know, just program that thing over the network and then you go.
CHUCK: And then finally, one last pick and this is something that's related to metrics, something that I have used often on for a while, is Metric Fu. And I mentioned it during the podcast but, I just wanna plug it here. It’s a pretty nice collection of tools. The output, I don’t love the lay out but it does give you a lot of information about your code and what is going on there. Though I do really like the way Code Climate kind of boiled it down so, you know, I’d definitely going to be looking at that some more too. Anyway, so those are my picks and before we have Bryan do his picks, I just want to have him because we really didn’t discuss what exactly Code Climate (I'm sure you’ve kind of infer it) but Bryan, can you just sum it up in a sentence or two, what Code Climate is about?
BRYAN: Sure, yeah thanks Chuck. So Code Climate is a hosted service that will generate these types of metrics that we talked about today, for your Ruby code bases, on an on-going basis. And it gives you a UI, web-based UI where you can sort browse next for them, show them with your team. It also has a component where it will look how things were trending over time and send out emails to your teams. So, it’s a way to take some of the stuff we talked about today and really integrate it in your process.
CHUCK: Alright, cool. What are your picks?
BRYAN: So I just have one pick which is, new information not yet announced, GoRuCo will be held again in New York City. This is the, I guess we’re saying sister conference of Go GoRuCo Josh I think?
DAVID: Yeah I believe Josh most describe it as go GoRuCo’s hot older sister.
BRYAN: So, right, so go goruco’s sister will be coming to New York again on Saturday, June 23rd. So this is the first announcement of that date. Mark it off and we’ll have a SFPR as well as more information about, you know, what we are doing in the conference this year but Saturday, June 23rd, new York city. That's a lot of fun, good excuse to get to New York for weekend.
CHUCK: Alright, sounds great. Really quickly, few other things that we need to go over, we’re going to be reading Land of Lisp. We should be reading Land of Lisp and we will be talking to Conrad here in about two weeks. I'm also going to be, I just wanna thank our sponsor New Relic for sponsoring the podcast and you can get us in iTunes or through RSS on whatever your favorite podcaster is. And beyond that, we will catch you next week!