RR David Heinemeier Hansson
- Published on:
02:46 - instiki
06:11 - Git Compare
- Git Blame
- Replace Code You Don't Like
- Yehuda Katz
- Aaron Patterson
- "I work on the stuff that I need." - David's role in Ruby on Rails
07:55 - 37Signals
- Code Comparison and Determining Which Code is Better
12:48 - Code Value is Best Determined by Code in a Real Project
14:12 - resourceful
16:14 - YAGNI (You Ain't Gonna Need It)
16:54 - "I try not to extract any code or functionality unless I've seen the problem at least 3 times."
18:50 - PDI (Please Do investigate)
20:35 - Strong Parameters
21:48 - Show the Evidence with Real Code
- The Before & After
22:50 - Show Improvement by Implementing Change
22:53 - Nested Parameters
23:30 - Internationalization
25:38 - Disconnect Between Design Patterns/Abstract Ideas and Implementation
40:40 - DCI
41:27 - Law of Demeter
45:00 - Feel the Pain, Understand the Pattern
52:06 - Front End Development
- "Is the code better?"
54:11 - Ember.js
- Client-side MVC
59:24 - 37Signals (Cont'd)
CHUCK: I think we should ask him hard questions about Node.js.
JAMES: I was told on Twitter I could just ask you about Facebook and that ought to get you mad right off the bat, so.
DHH: You know, I'm in a cheery mood. The stock is down another 4% today.
[This podcast is sponsored by New Relic. To track and optimize your application performance, go to RubyRogues.com/NewRelic.]
[This episode is sponsored by RailsThemes.com. Have a website only a mother could love? Then you need a theme. Go to RailsThemes.com and sign up for an early access and when they release, you'll be able to check out and use their themes on your Rails app.]
CHUCK: Hey, everybody and welcome to Episode 56 of the Ruby Rogues podcast. This week on our panel, we have James Edward Gray.
JAMES: I'm sorry. I'm one of the guys not named David on this podcast.
CHUCK: Yeah. We also have Avdi Grimm.
AVDI: Hello from Pennsylvania.
CHUCK: Josh Susser.
JOSH: Hey, good morning from San Francisco.
CHUCK: David Brady.
DAVID B: Fully medicated and ready to rock.
CHUCK: I’m Charles Max Wood from TeachMeToCode.com. And this week, we have a special guest and that is David Heinemeier Hansson.
DHH: Hi everybody from this afternoon in France.
DAVID B: Oooh…France!
JOSH: Where in France are you, David?
DHH: We're down nearby Nice.
JAMES: Well, I didn't know we were supposed to call in from exotic locations today. [Laughter]
JOSH: I always do that, so I'm covered. [Laughter]
DHH: I don’t always go on Ruby Rogues. But when I do, I do it from France. [Laughter]
DAVID B: Very good.
CHUCK: So David, do you want to introduce your self really quickly?
DHH: Yeah. I was…Oh, never mind! [Laughter]
DAVID B: We just had to get that joke over with. Now, we can move on. So Dave, tell us about your self.
DHH: Well, I mean, since this is a Ruby podcast, I think questions exploring my opinions on things are far more interesting than me talking about what I did in the 5th Grade as a dumb whack. So, let’s get into that. [Laughter]
AVDI: Okay. So, share a little of your resume with us then.
DHH: From the 5th grade to the [inaudible] class? Let me see.
AVDI: You can start with Ruby.
DHH: Oh, okay.
CHUCK: Have you written any software that anyone's ever used? [Laughter]
JAMES: That we have heard of?
DHH: It was funny actually because we were looking yesterday and somebody brought up Instiki which was actually the first piece of open source software I ever released.
JAMES: I actually used that.
AVDI: I remember that.
DHH: Somebody's still using that. And not only are they still using it, they are still developing on it. And I pretty much abandoned the project about a decade ago and it's still going strong now at version 0.19.3 or something like that. It's just kind of fun to see that the software is forever in many cases even if you lose interest or there'll always be somebody or usually there is somebody who will find it and do something with it. So, it's just kind of fun.
JAMES: It is forever but apparently it will never reach version 1.0, I guess.
DAVID B: It still hasn't shipped.
JOSH: We can start a betting pool about which will go 1.0 first, that or Rake.
JAMES: Ouch! [Laughter]
CHUCK: I actually had a long talk with Jim Weirich about Rake 1.0 at Rails Conf and he had some different ideas about that.
JOSH: I think we're going right to 2.3.
CHUCK: There we go.
JOSH: Or 1.97 or something like that. David, I actually hacked on Instiki way long ago.
DHH: Oh, really?
JOSH: Yeah, I've played with the code and everything.
DHH: Awesome! It was a fun project. A fair number of the ideas sort of came out in the open before Rails was released. And actually for quite a while, they were running on separate code bases even though obviously, lots of Instiki had Rails-inspired elements to it. It also ran off -- what was it called? Madeleine which was a…
JAMES: Yeah, that was great.
AVDI: Oh, yeah.
DHH: Optic assistance engine which was kind of a sort of a fun way that people liked all the way up until their [inaudible] got corrupted and then swore it off forever. So, it never seemed like that. That actually took off any further from those original attempts at it.
JOSH: Do you ever go back and look at your old code and say, "Wow! That was really cool!" Or, "Wow! What was I thinking!"
DHH: It's funny because the two main projects I'm working on, Basecamp in Rails, are full of code that was written ten years ago. I mean, not all the code in Rails have been rewritten and certainly not all the code in Basecamp either. So, there are tons of sort of elements. I do a git blame on a piece of code in Basecamp and I see 2003 or whatever, as the check-in year for that line which is just a funny thing to see. But, I generally just have the principle that if I see code I don’t like or no longer like, I rewrite it. So, the only kind of code that's still around from '03 is code that I'm actually content with because if I wasn't, I would have been rewriting it already.
CHUCK: I can totally see that. Who wrote this piece of -- oh well, that was a long time ago.
DHH: So, I mean, most of the code, if you take both of those code bases, have been rewritten either because we wanted to do something different or because we learned something new. So, those elements that are still around are around because they were either good the first time around or they're just non-consequential. But it is funny to do a git compare on a piece of code sort of thinking, "This is kind of an odd construct.” And then see it was something you did five years ago and there is nobody else to blame. Although, what's actually even more interesting is you do a git blame and you see somebody else touch these lines and you're like, “Who the hell came up with this concept?” And then you dive down to git blame and see, "Oh, the guy actually just changed the comma.” You're still to blame for the original sign of this feature.
JAMES: Yeah, git blame is always a double-edged sword especially when it points to you as the culprit, right?
DHH: For sure.
JAMES: So, I'm going to ask you a little bit about managing of open source projects since you obviously manage a very big and popular open source project and…
CHUCK: What's it called?
JAMES: [Chuckles] What's it called? Yeah. Ruby on Rails, have you heard of that? I think it's gone through kind of phases, like I mean, I feel like you were very heavily involved and doing most of the main coding toward the beginning. And then, you know, during maybe the Merb merger, you know, Yehuda got a lot more involved and maybe did a lot of development, at least in some areas. And nowadays, you know, Aaron does a lot of it, the driving, in some areas. I just thought you'd tell us a little bit about what your role's been like and how it's changing over time.
DHH: Sure. So, the fundamental of my involvement with Rails has been the same as it has been from day one which is I work on the kind of stuff that I need. I create features and I fix bugs that personally affect the work that I'm working on which is generally because it's involved in some sort of 37Signals product. And I find that that is the best mode of contributing to open source software, is when you work on your own problems, because you tend to have a much better sense, much keener sense of what is quality. When you are trying to solve other people's problems, you're constantly working by proxy. You're constantly trying to find out what is it that they really want. And coming up with great APIs and a great framework code of guesses like that is just not a great way at arriving at good software. It has a tendency to become overly convoluted, too many options, too many configurations because you're trying to make things flexible through all the possible maybe's that exist out in the world. And the kind of code like that just [deleted] and I think that that's why lots of professional tool vendors and programmers turn out poor quality code. Because once you get to the point where the only thing that you work on is the tool itself, you lose connection to that parameter of quality which is what I actually want to use this. And not just in the theoretical of, "Can I imagine that I would want to use this but have I actually used it in the real world?" Because it is ever so easy to come up with all these hypothetical situations and code examples and code demos that look and smell great when they're just this scaffolding idea of what you need for a Read Me file or a demo. And then, as soon as you try to apply it to a real project, it all breaks down, which is really the guiding principle behind all of the Rail's decisions that I try to make. "Does this actually work for real code?" And not only does it work for real code, "Is it better?" So, you look at a piece of code and you rewrite it in the new form and you introduced a new feature and then you compare the two. Preferably, you compare the three or the four where you have a few instances of where it's being used. And then, it will be clear as day which is better and which is worse. And that's why I generally sort of -- I'm not all that interested in just discussing code in the abstract level of design patterns or just design language because it's so easy to get lost in just the words. When you look at the code, there's no getting lost. Most reasonable people will agree when you compare two pieces of code, which is better and which is worse. Which is actually…
AVDI: I have never found that to be the case. [Laughter]
JOSH: I'm with Avdi on that one.
JAMES: I think the problem is we don't always work with reasonable people maybe. I don't know.
AVDI: Well, what I was thinking is you're talking about basically like a visual sort of a visceral comparison of two pieces of code like which is the one that is clearly to you, you know, more elegant than the other. Is that accurate to say?
DHH: Yes. That is 90% of the value of evaluating techniques or approaches to programming as it relates to the kind of work that we do, comes from the visual aspect of it because it reveals every other attribute that's worth discussing.
AVDI: So, I guess, my question is, you know, I've seen a lot of code, in my experience that looked great. You know, it really seemed -- maybe it seemed clever or maybe it seemed like it solved the problem in a very direct way. But what wasn't obvious was the effects that that piece of code then had on maintainability over time as people tried to extend it or tried to extend the things that it touched. So, that's where I see like that method of comparing things falling down. I'm curious how you deal with the not so obvious consequences of, "Okay, this looks great in isolation.” But what are the long term effects of having this, you know, how it touches other code and stuff like that?
DHH: Well, I think it's two parts. The first is the scope of the comparison. I completely agree. If you're just looking at five lines of code and somebody injects something that can write those five lines in one line of code, that might, on its surface, seem appealing but it's completely uninteresting which is why comparing code like this on the Read Me or example level is meaningless. The only type of comparisons that are worth doing are comparisons of code from real projects. Because real projects just have this uncanny way of exposing all these flaws and faults and also why you look at not just one instance of something but three or four. So, if you're introducing a new technique to a code base, usually you do that because you've seen a pattern. It's not just because you've seen one area of the code where this would be slightly better if you introduced some change. You've seen this pattern multiple times in your code. And real code has this wonderful sort of tendency to be same-same but different. Like you're trying to abstract a pattern that you've spotted three, four, fives times in your code base. And all of those spotting or sightings, they're similar but they're not exactly the same. So, I think that's what really helps tease out is this actually a good abstraction. And that's why sort of naïve extractions that I've seen, for example, if you just look at this scaffolding code that comes out of Rails, for example, like just a controller. If your only objective was to write that controller that's being generated by default in the shortest amount of lines with the least amount of duplication, you will come up with a framework that's completely different than Rails. It's just not optimized for making that one controller look good. Which is why when I see stuff like resourceful and so forth, I look at that and say, "Yeah, that would be great." If all we did all day long was write scaffolding code, that would be a wonderful optimization. I never write scaffolding code. Scaffolding code is the starting point. What's interesting is the kind of optimizations that are still relevant after the application does something useful. And scaffolding applications generally do not do something useful. The second part of that is then like, so let's imagine that you've looked at these four, five, six instances of an optimization from a real application and you come up with a change or an improvement that helps those five areas, right? Now, the question is, "Is this long term maintainable?" That question, to me, is irrelevant. This is fortuneteller territory. If you concern yourself with things that you cannot see and cannot touch today, you cannot evaluate them. And that's, to me, the same as pick up-front design. It's trying to guess what the future is going to look like and how the tools we design and shape today might best fit the future. It's a completely futile exercise in my book. No, actually it's worse than futile. I think it's harmful. I think it's the same sort of tendency that leads to -- what do you call that? Guess code. Like, "Oh, let me just add this one feature, this one option, to this piece of code because I might need it tomorrow." That's the worse kind of programming to me. That's the kind of stuff that makes your code base overly configurable in ways that actually ends up making it rigid and hard to adapt and change. Because once tomorrow actually rolls around and once the requirements of tomorrow are actually here, they're never what you guessed them to be and they will always require different changes.
JOSH: Yeah. And the Agile word for that is YAGNI. [Laughs]
DHH: Yep, absolutely. I think YAGNI applies just as well to all concerns of, "Oh, is this going to be maintainable in the future?" I just don't think that it's a -- it's not a relevant concern if the maintainability of the feature should be completely obvious at the point of implementation. And if you're worried that you haven't seen enough, then maybe you're just working off one instance which is completely a fair concern. If you only have one area of the code base you're trying to improve, it's a fair concern, thinking, "Is that actually going to apply equally well elsewhere?" Which is why I try never to abstract any pieces of code of functionality until I've seen the proper release three times.
JOSH: Yeah, that's interesting. You know who Ralph Johnson is? He's one of the Gang of Four Design Patterns book. He did a lot of Smalltalk stuff ages ago. He's pretty awesome. And I saw him do a talk at OOPSLA way back when and he was talking about frameworks and reusable frameworks. He made a very simple point that we don't ship code until we've tested it and frameworks are meant to be reused. So, you can't really ship a framework until you've not only used it but you've reused it. Yeah. So, that's a very short way to say what you, you know, went into a lot of detail about which, you know, was really interesting to hear that perspective spelled out in so much detail.
DHH: And the only reason I know this is because I've tried the other way. I tried multiple times and multiple erasures of features in Rails have come about because you get too giddy about an idea. And you get so giddy about the idea that you want to implement this improvement before you've extracted it or extracted it. Before, you have actual working code that you can do it before or after on and see did it get better or did it get worse. And every single time, I've gotten ahead of myself and tried to do this sort of preemptively guessing the future, it's turned out to be [deleted] like the code was just bad. As soon as I had to use it, it was like, "Oh, oh, oh!" All these areas of concerns that I had considered. But I came to the wrong conclusions because I had nothing to actually look at. So, I was just estimating and guesstimating and doing all sorts of things that will lead to crappy code.
JOSH: I remember for a long time, the policy in Rails for, you know, when people would say, "Oh hey, I want to do this new thing in Rails." You know, aside from the PDI response, which I essentially grew to love…
CHUCK: PDI response?
JOSH: Please Do Investigate. It's interesting, a lot of people took that as a sort of a, you know, the Rails Core giving them the finger. But it was actually like, "No, this is a good idea. Go do the work and we'll take a look and see what it looks like." So, I thought that that was a great way to handle all those feature requests.
DHH: As a side note in that, PDI is actually, to me, the most sort of enduring thing you can say about a suggestion somebody has. Like they had the problem, they had the insight, they have the knowledge to fix it. How the hell am I, somebody not with your problem, somebody not with your insight, going to do a better job at fixing your problem than you are? I mean, to me, PDI was often, as you said, sort of position, "Oh, this is an arrogant response.” Like, I don’t want to deal with your problems. To me, it's the complete opposite of arrogance. Like, it is saying, "I don't know. You have the information, you have the knowledge. You're the one in the position to do the work."
JOSH: Yeah. And it took me a few times to figure out that that's where you were coming from and then I was like cool with it. But the policy in Rails Core for a long time for future requests and things like that was, "Let's try it out in a plug-in."
JOSH: Which was, I think, a really nice way to force that process that you just described.
DHH: And we've gotten even more militant about it recently. Pretty much everything that is of any consequence will start out in a plug-in these days. For example, strong parameters which is the sort of new approach to dealing with mass injection issues. It's a plug-in. It's even a plug-in where making that plug-in, I was 98% sure that this was absolutely the way to go. But these days, with sort of the plug-in structure that we have and the way we set these things up, makes it such there's real penalty for starting out any kind of new feature in the framework as a plug-in. And not only is there is no penalty, there are a laundry list of benefits including you can use the feature right now which is, for example, true of strong parameters that's going to be a feature in Rails 4 but you can use it now in Rails 3 and whatever else people have chosen to back port it to.
CHUCK: So, this leads me to another question then and that is, if you're working on and adding the stuff that you need to Rails and somebody else, you know, investigates, builds a plug-in, builds an engine or whatever, and, you know, submits it, how do you decide which of these ideas, which of these implementations make it into the next version of Rails? Because they won't necessarily solve your problem but they may solve 60% or 70% of the community's problems.
DHH: Sure. That's when you go back to ‘show me the evidence’. And to me, ‘show me the evidence’ is show me the before or after of real code. That's always the baseline. And whenever anybody proposes something and it's not immediately obvious, and even if it is immediately obvious, I want to see the before and after. Because as we just talked about, that is the only reliable way I have and know of to evaluate APIs that could go into the framework, and it becomes so obvious. Even if it's not my problem, which certainly does make it harder, but if it's somebody else's problem, they can present me with three, four, five different code examples for like, "This is what the code looked like before, then I came up with this thing and this is how it looks now." I can get pretty close to sort of discerning, is this an improvement or is this a step backwards? And then, I mean, all these things can make it in. That's why it's fairly rare that we have full-on computing implementations for the same problem. It's happened.
JOSH: Yeah, nested parameters or nested attributes. There were like two or three different proposals on that one. Okay, but continue.
DHH: Yes, and sometimes that is how it works out. And nested parameters is actually a good example. So, most of the apps that I've ever done has never needed nested parameters. Maybe it's just the main I worked in or the way we do our UI or any other reason you could pick. I've never had that be a real problem for myself. So, I was loathed to just make a snap decision before that had had a really long time to play out. And we've had other things like that. Internationalization is probably the biggest one. Like for such a long time, we like said, "No, this is not going to make it end because all the proposals I'm looking at now, I don't like. So, let’s just keep churning." And the community churned for another 18 months or so. And I think like three of the major plug-ins got together and said, "Well, let's just at least create a base and just extract the lowest common denominator." And it turned out to be wonderful and I since used that feature and I think like, “This was great.” This was the process and it really worked. It takes longer that way, absolutely. It doesn't resolve as quickly. When I'm working on features that I care about deeply myself which is features that I would use myself, the decision process is just much faster. And that's just simply -- that’s how it is. The closer you are to having sort of an overarching responsibility for a framework and then being interested in certain aspects of that framework in sort of in particular, yes those will move faster. I don't know of another way.
JAMES: The community seems really interested in the moment in object-oriented design principles or seeing things like DCI, isolated testing projects. I know you mentioned one earlier which I can't remember now. But Objectify, you know, is a new project done along these lines. And I get the impression from reading things you write, in particular, that you're not really keen on this movement. And I think I understand now because I've been listening to you. And I'm assuming it's because you feel like we're discussing these concepts in the abstract whereas you would rather talk about the actual implementations and the benefits that it leads to. Am I understanding that right? Or what do you think about the whole object-oriented fascination at the moment?
DHH: I think there's a disconnect in this whole discussion which is the disconnect between the lofty design patterns and design ideals which are very easy to talk about in a convincing manner. You can convince a lot of people that say the Law of Demeter is a great design principle. And your code will be so much more maintainable and it will so much more wonderful if you follow it. And as long as you explain it in a very abstract way, with small code example like snippets, it's incredibly convincing. And that goes for pretty much anything. No matter how [deleted] the idea is, you can convince people as long as you stay on the abstract plan or with small enough pieces of code. Now, as soon as you then try to move beyond that and actually apply those principles or those ideas to a larger code base, there comes the truth as we just talked about. You will see the code and you will see whether it's better or whether it's worse. And I think that the case for a lot of these, which I actually think are completely misnamed, calling the more OO principles sort of sets a false dichotomy up between like, "Oh, this is OO and what we're doing is not OO," which I think is complete [deleted]. This is cherry picking of a few principles like single responsibility principle and so forth that are being heralded as being, “These are the be-all and end-all of what is OO,” which I think is such [deleted]. And then, they're being applied to what I think are just bad ideas. And I don't say that lightly because, I mean, I seriously try to live up to the principles I talked about in my Rails Conf keynote which were ‘Keep an Open Mind’. There are great ideas being hatched all the time. And Jason Fried, my partner at 37Signals, wrote up a thing called ‘Give it 5 Minutes’ which is that in programming, as in anything, it's very easy to have a knee-jerk reaction. I think a lot of people have lots of knee-jerk reactions to stuff in Rails 3. So, I'm trying to be aware of that for myself. And I'm trying to give things much more than just five minutes, more like five days or five weeks or five months. And in some cases, our spec maybe even five years. And what I just found with sort of the principles we talk about here, Objectify in particular, is that when the rubber hits the road and you look at the actual code and you compare the before and the after, it is more complex with no discernable value. Maybe there is discernable value if you start again moving things out to that fortune teller line of thinking, "Oh, this will be more maintainable." Maintainable to me is such a weasel word. It's a way to sort of avoid talking about the here and the now, the concrete. The things we can see and we can touch and we can actually compare and then move it out into the abstract, the vague, the things we can't compare, to sort of the hand wavy end of design discussions which I find generally to be an uninteresting domain. Which is also why I generally don't care about these discussions until people put forth code because as soon as the code is there, we're back to the concrete, we're back to just saying, "Is this better or is it worse?" And if you take Objectify, I really struggle to imagine people seeing the before and the after code and thinking, "Oh yeah, this was better. This is simpler. This is nicer. And this is sort of a reasonable amount of abstraction.” This doesn't unnecessarily introduce new abstract concepts and names that end up not really doing anything for the underlying code. No, I mean, if you look at that code and you look at the before and the after, you will see what the hell are we doing with these additional four patterns in policy my this and policy my that, and it doesn't improve anything. Nothing gets better. That's what -- to me, I really just, I mean, borderline get upset about which isn't always a fault of mine.
JOSH: Yes. So David, I think you have a good point there. But as many things, it's a matter of perspective. And you have a really strong understanding of Rails from soup to nuts and top to bottom and you understand how all the pieces work together. And many people coming to Rails, you know, it's just like they've stepped into the foyer or the entryway of a building and that's pretty much all they get to see. And they think, "Oh, you know, if I rearrange the furniture in here and you know, change where the doors are, things will work much better.” But they don't really know the whole building yet and how to make things work or that they're wasting time in just the smallest miniscule superficial part of the problem.
JAMES: I want to add something to that.
DHH: I think that's true. Let me just add. It think that's true but I don't even think that's the main problem because I love the idea of the newbie coming in and not being bound by knowing everything about how Rails works. I think that the veterans of anything are often blind to the most obvious improvements that you can make because they just dull their senses to the obvious deficiencies that are out there because they just don't notice them anymore.
JOSH: Yeah. That can happen.
DHH: I think that that absolutely can happen. So, you can look at it at a reasonable small scale. Like if you come in and you've just seen the foyer, you don't know how the rest of the house works, you can still make sort of rearrangements to the furniture that are net positive without understanding the rest of it. But you still have to be evaluated on like, "Oh, does the couch work better over there or not?" And I think that that's really -- that’s why I love programming. That's why I think programming is so much better of a disciple than so many other disciples that have a very hard time making their abstract ideas into something concrete, like we can go from really abstract philosophical thinking about certain problems. And then, at the end of the day, it still has to be executable code. And I think that that sort of transformation is the beauty of it which allows us to cut out most of the [deleted] because as we just talked about. Once the code is written, you can just evaluate that there and you'll see instantly whether the Emperor has no clothes which I think is the case for a lot of this so-called OO approaches to ‘let's rearrange the furniture’.
AVDI: So, what do you think OO is when you say ‘so-called OO’?
DHH: It's tying data and functionality back there together. To me, that's sort of the baseline. But there are all sorts of aspects of that we can talk about. But I think that that, to me, is the underlying principle that the state and the behavior lives together.
AVDI: You don't look at it from like the behavioral perspective of -- it's about modeling behavior.
DHH: Well. So is the functional approach.
AVDI: I mean, like when I say that I mean like the, as you say [inaudible] define object oriented programming as a system for basically getting rid of data almost entirely and modeling behavior between things that are almost like independent cells.
DHH: Again, that in the abstract sounds fine and then somebody will introduce single responsibility principle and they will do a literal reading of that pattern and then, they will apply it in…
AVDI: That’s not a pattern. That’s a principle. I mean, I think it sounds like you're kind of conflating like… [Crosstalk]
DHH: …the application how you want to do it. Do you want things in larger pieces or you want them in smaller pieces? And I think that this is the kind of sort of intellectual exercising that quickly becomes boring to me because it… [Crosstalk]
AVDI: Right, but well… [Crosstalk]
DHH: …from the concrete nature of what we're trying to do.
AVDI: So, let me maybe try to bring a general perspective on that because I guess I found myself in a position of talking about a lot of this stuff. But I don't talk about it just because -- I mean, I will admit I enjoy talking about it. I enjoy thinking about abstracts. I enjoy looking at things that I've seen, I've seen over and over again in many code bases and sort of trying to understand like the abstract principle of what's going on there which is kind of what you were talking about earlier. But I mean, the reason that I talk about it a lot is because I find myself in position of seeing sort of anti-patterns come up in code bases over and over again. And so, I think it seems a little dismissive to say, “Well, people are just talking about this stuff because they enjoy talking about it.” When most of the people that I'm talking about this stuff with, it's because they are in a panic virtually. Because their projects are coming which used to be moving fast are now, they're talking forever to get new features out very often because, for instance, bits of code have many different responsibilities. And so, it's impossible to get something new in without breaking a bunch of old things. So, I mean, is it fair to say that that's just sort of, you know, abstract intellectual noodling?
DHH: I think it very quickly divulged into that unless you stay at the code level. So, unless you keep it revolving around those specific pieces of code that you saw and the sort of application of some principle or some pattern and how that improves it, then yes, it so quickly becomes the noodling of sort of philosopher's [inaudible]. And that's the sort of dilemma as we just talked about. The very appealing part of programming is that it contains both sides, right? So, we have this sort of the abstract ideas of why we do things the way we do. And then, we have the product that comes out of that which is the code. And I just find myself getting bored with a lot of discussions that tend to move very quickly from this, "Oh, here's this piece of code," which is usually oversimplified and remove from the real world very quickly. And then, we move into these abstract discussions about one principle or another without staying in close contact with the code. And that just is not a very interesting sort of exercise to me.
JOSH: Which is unfortunate because I think the original work done on design patterns, all the people involved in that were like up to their elbows in code all the time. And they extracted that knowledge from their concrete experiences. So, I think you're really right about that stuff needs to be grounded.
DHH: And I think, actually, if you look at the Design Patterns book sort of the Gang of Four book, I think it's one of the most unreadable books ever written.
DHH: And I think it's just a terrible piece of sort of attempt at teaching versus if you look at sort of other much more grounded, much more concrete pattern level books. I think Fowler's book, the Refactoring book and the Patterns of Enterprise Application Architecture which is sort of a very fancy name for describing something that was actually incredibly concrete. Those are, to me, much better approaches at it where it’s sort of like, we're not interested in the patterns themselves and just talking about them on this abstract level. We're interested in like what happens when you apply this pattern of principle to a piece of code and this is how it looked before and this is how it looks now.
JOSH: Well yeah, but the first time you try something, you know, you get some of it wrong. So that, they're the first design patterns book. They didn't know how to do it.
DHH: Sure. Obviously, sort of lots of credits and kudos for coming up with a whole idea of describing these things and so on. If you look at the practicality of it, this is being held up as, "Oh, this was the original design patterns book." And I think it's entirely at that level that this does not interest me. And maybe some of it is because they were trying to solve how to create text editors for desktop platforms in C++. And a lot of these patterns and principles are very context specific. And they just seem like ranking if you inject another language and another domain into it. And a lot of these problems just disappear because they're just not problems in that domain anymore. So, that's some of it. But I also think a large part of it is just how sort of they got carried away a little bit in the abstractness of it which, I mean, that is this occupational hazard. We are dealing with sort of abstract things even when they are at the code level. So, I'm completely sympathetic to how you can get lost in that. I've certainly committed that sin many times. And that's why I'm so passionate about it because I know that every single time I get down that trajectory and I divorce myself from looking at the actual before and after code, I get lost and thinks that they are not mattering.
JAMES: So, I want to inject one thing here and then I promise we can move on to something else. But I too am a big object geek and I like starting the object stuff and I do read a lot of the abstracts and the new ideas in your DCI and all that. And I like a lot of what you said about how you have to keep it on, we would do this because this becomes this and that's obviously better. I definitely agree with that and couldn't agree with that more. And I love your idea about we should give it five minutes or we're up to and maybe quite a bit more and see if we still think the same. And I agree with all that. But I think, for me, the reason that these kind of discussions hold value is that until we talk about it in the abstract and compare it and get ideas, then I may not have the ideas about how to get from the before code to the after code. It's that, I look at something and I see, “You know what? This can be better.” And I wish I could make it better. And then I think, "Okay, what if I apply the rule of DCI here?” Or, “What if I reduce this to this pattern?” And then, like you say, absolutely, I believe we should look at that objectively and say, “Yup. That's better.” Or, “Okay. No, that's the wrong way to go here. It's not the thing we should be trying.” But until I have that foundation of knowledge, then that may or may not have enough good ideas to actually get it to something better. So, that's why I believe those kind of things holds them back.
DHH: Sure. The main issue I have with that is it's kind of like I could have good knowledge of all kinds. Once you name something, it gives it often too much credence as being a good idea. Let's take the example of Law of Demeter. Just in the name, it says Law. To me, that just gives that concept idea way too much weight. And what I find is that when people learn about things that have names like Law of Demeter, like they think they have to [deleted] follow those laws or else, bad things will happen. Like the critical part of evaluating the before and after code is so easily switched off when you have these fancy sounding patterns and principles especially if they are sort of had enough hubris to include the name law as part of it that people will just slaveously follow them to bad ends producing code words that after is worse than the before. So, I mean, it's very easy to take that whole idea and just classify that under anti-intellectualism which I don't think that's what it's about at all. I think it's about having more than a healthy amount of skepticism towards the sort of myriad of ideas of how to design software that are out in the world and sort of having a little bit more of a healthy balance between delving into the abstract, the patterns, all the stuff that is divorced from the lines of code that we eventually have to boil all this stuff down to anyway.
JAMES: I just wanted to say that I do agree with what you just said that I play a lot of chess. And in chess, we study openings and sequences and there is almost like laws. And that will make you good when you get to where you know what those are. But to actually get to great, you have to go the point where you deviate from those lines to get into what you want to get into. So, I totally agree with what you just said that you should take on these principles, you should learn how to apply them, you should figure out how they can change your code. But remember that each situation is a case by case basis. And there's time when you got to break the rules.
DHH: And even more so. I mean, to me, it's almost like I want to flip that. There are times we need to follow the rules. That's more like how I refer to it because it's not as this sort of catalog or this rule book that we have of patterns or sort of like that is the law and then occasionally you can be disobedient. I don't think that's the case. I think that occasionally, it's helpful to follow these principles. I think that's a more helpful way of going into it. And the other thing too is that -- so, we were talking about like, before you become an expert, you don't necessarily know like how to design software in a good way. Like if all you know is just laws like, "Oh, it's Law of Demeter. I'm not supposed to call into this deep hierarchy because that's what the law says.” You've learned nothing and you will know nothing when you actually hit something that deviates in the slightest fit which software does all the time from those prescriptions. So, therein lies no deep knowledge. The deep knowledge only lies in when you actually understand why this is helpful in certain cases which is the problem I find generally with the sort of design patterns, and learning them before you've actually stubbed your toes. Before you've had the hurt of not knowing like how bad things could become without that principle, it's very hard to internalize and understand why these things are actually helpful and when they're helpful and sort of grow and learn from that. Like my preferred path, actually, of learning is that first, you have to do the wrong thing. You have to do the bad way to appreciate and understand the good way. And I think that that is doubly so the case with design patterns and doubly so the case with design laws and all these other principles that we're talking about that you have to do it wrong first to appreciate why doing it so-called right is helpful in these certain situations.
JAMES: So can we…go ahead.
JOSH: Yes. I think that's very similar to what happens when people enter a new language or come to a new language. We talked about this on an episode a while ago about seeing people write Fortran programs in Ruby, or Java programs in Ruby, or what have you, where people are -- you have to do it wrong for a while. But people are basically working at the limits of their own experience. And you have to work there for a while to be able to expand the limits. Yeah, you can use tools wrong and that's a good way to learn to use them right. I think I've mentioned it on the podcast before that one of my favorite sort of conceptual tools is Wittgenstein's Ladder which is the whole thing about we have a ladder of concepts. But to be able to get to the top of the ladder, you have to move up the rungs and go through the stages of learning.
DHH: Yes, yes. Which is actually also, I mean, at times, one of the most frustrating parts of being involved with Rails that, to me, you only really appreciate what Rails gives you before you've tried to do everything Rails does without it.
DHH: It does so much. And it's so easy to lump all of those solutions in this bulk or weight or what used to be the -- what do we call it? Not, mono…monolithic, as a monolithic structure. Those things are so easy to -- those labels are so easy to apply before you've actually hit the problems that something is trying to solve. And that's why at times, it's frustrating. But you also have to know that that is how learning happens. People will start out, which is healthy, like that's what use those newbie insight, they will start out thinking, "Oh, we don’t need all this [deleted] because I've not hit the problems yet." And then once they hit the problems, they will develop the appreciation for the solutions.
AVDI: Yeah, I think that's absolutely true.
DHH: As goes with the [inaudible] which is also why it's actually not helpful to try to speak these things up too much, just talked about. You can't just shelve the most sophisticated framework on somebody and the most sophisticated design patterns on somebody and then, "Oh, voila! We have a great student of programming here. We have a great craftsman of programming." These things take time. Not necessarily in count of the time. I believe somebody can become a fantastic programmer in, say, nine months which I know lots of people don't believe that. Most companies hiring people don't believe that, like they're always asking for years of experience. I traded Rails after working with Ruby for, say, three months and I think that it's all about like there is no speed limit in terms of how fast you can learn this stuff. But there is a path or trajectory or road you have to travel to learn it which includes sort of stubbing your toes and making all these mistakes along that path. You can go very fast doing that. You can make tons of mistakes very quickly and learn from them but you have to go through that cycle to appreciate and truly understand the sort of disillusions on how to use them.
AVDI: Yeah. I get a lot of people saying like, “So, here's this code that I wrote but how should I make it better?” And my first question is always, "Well, how is it hurting you?" DHH: That's the first order I would say. Like, if you can get somebody who's actually like, "I'm experiencing hurt." That's the perfect spot to be in for learning.
DHH: The second best is, of course, to demonstrate hurt. But you then have to have that [inaudible]. You can point to a piece of their code and like, "Do you know that A, B, and C? And this is why this duplication is here." Or, "This is kind of rigid," or whatever. But they have to get to that insight before you can then, "Oh, here's what I propose."
AVDI: Absolutely. But I guess it's just difficult like you can even totally do that one on one. It just gets difficult once you start wanting to share knowledge in a larger sphere because you're going to say something that might mean a ton to somebody who has hit the same pain points that you have. And then, somebody else out there that is newer is just going to sort of ape it blindly without realizing why they're doing it. And I don't really know -- I mean, maybe you have some insights. I don't really know how to prevent that.
DHH: I don't think there is a good preventive. Sometimes, the prevention is just it's going to take time. And then, if they're going to ape something, then they're going to stub their toes when they cargo-culted a solution in an area where it doesn't fit. And then, they just hit the hurt later. But the hurt they must hit. I mean, there's no way around that. So, part of it is just that it's going to take time. And also, it's going to take willingness. There are plenty of people who are entirely content getting to Level 3 not knowing that there's Level 55 available or actually even knowing that there's Level 55 available. They are just like, "Level 3 gets me what I want. I have an application that sort of kind of probably works." And to me, by the way, that's wonderful. I think that the [inaudible] of programming is one of the sort of most beautiful things that we have. You can have people who know very little can make software. I mean, how magical is that? That they can solve their own problems knowing so little which is why I still hold immense appreciation for things like PHP that I think that they bring truly great things to the world by enlarging the pool of people who can have access to programming computers.
JAMES: Let me ask you one more question which I think kind of ties in to everything we've been talking about but also, is something people are interested in. When I asked on Twitter what I should talk to you about, about every third response was something to do with front end development. And that definitely seems to be a big focus these days with things like ActiveModel::Serializer and, of course, Jbuilder. And Rails has, I think, been kind of having that internal debate about how do we go with this. But at the same time, you posted that blog post about how you guys are doing Basecamp next, the big Russian Doll strategy, really focused on caching and stuff like that which I think was kind of eye opening that you guys are taking a not real heavy front end development approach and just kind of using what Rails gives you to the best of their ability. Do you want to talk about that in that process?
AVDI: Yeah. And I want to plus one like everything you just said, like every sentence. And I've been through a little experience in the last couple of months trying to use Backbone and do client-side and stuff and it's pretty painful. And you talked about a lot of these things, evaluating them using very subjective language. You talked about it feels better, it's more pleasurable. And as someone who has a lot of experience doing this kind of work, you've sort of taken all of these concrete objective measures and aggregated them up into these things that sound subjective. But I agree that there is a totally concrete things beneath all those evaluations. And I think that it's not appreciated by a lot of people just how, like what the difference is there. And like one objectively measurable thing is how long it takes to implement new features. And I found that doing stuff with -- I got server-side and client-side and all these things are going on at the same time. If I wanted to just add like one more value to a view of a model, I had to go hit six different files and it took me probably two or three times as long to get the feature in.
DHH: I completely agree. These things that sound objective or subjective are actually not that subjective because I find that most reasonable people actually agree. And as we’ve talked about it in the discussion, maybe there is a difference between what is a reasonable person. But of the programmers that I interact with on a regular basis, either in Rails Core or at 37Signals or elsewhere, I find that we tend to agree more than we disagree about these so-called subjective things, that the feel of something, once you dive into the concrete level, is actually very similar. And most programmers are the same and they enjoy over the same thing. At that level, once you're in the same cultural sort of sphere like somebody writing Lisp is not going to enjoy the same things in Ruby as I enjoy. And somebody writing Python, the same thing, but you talk to two Ruby programmers, like these subjective things are actually not as subjective as they sound. Like feels sound very individual and very personal when I think it's much broader, it's much more shared, it's much more of a cultural feel. Like somebody who's in the culture of Ruby, the range of what we feel about things is much narrower than we think. And then, these things boil down to something very concrete. It boils down to, as you said, the speed of which you can do things like how many mistakes you make and how fast you can move and thus how motivated you are doing these things. And I think that all these things are incredibly concrete and incredibly sort of important even to people who don't give a [deleted] about what programmers feel because there're plenty of those and plenty of business decisions about software made by people who couldn't give too [deleted] about what you feel is right or wrong. But thankfully, these things are generally in complete alliance. It's very rare that you're going to feel like this is wonderful and at the same time, you produce [deleted] buggy code that takes a long time to write. No. It's usually if you feel that it's great, it's going to go fast and it's going to be relatively faultless. And if you feel like it's [deleted], it's because it goes slow and you make a lot of mistakes.
CHUCK: Alright. Well, I'm going to end the episode here. We need to get into the picks and start wrapping this up. And before we do that, I just want to thank you again for coming on to the show, David.
DHH: Sure, my pleasure.
CHUCK: Alright. Well, let's go ahead and do the picks. Avdi, what are your picks?
AVDI: My pick is the unmute button.
JOSH: It’s unpick of the day.
AVDI: No. I honestly just wanted to use my pick time to say something which I didn't get a chance to say earlier, which is just a big ‘thank you’ to David. Not just for coming on the show but ten or so years ago when I started playing with this super fun language called Ruby, I had fairly low expectations that I would ever be full-time employed to write code in it. And Rails played a huge, huge part in actually making that a reality. So, thank you for that. It's been super fun.
JAMES: So, Avdi's pick is DHH which is no surprise because they both have great hair.
CHUCK: Yeah, absolutely.
DHH: I actually used to have a -- speaking of fifth grade, as long hair as Avdi does in fifth grade. So, inner stuff being in allegiance there on the long hair and the source of strength. [Laughter]
DAVID B: Did you still wear it in the faux hawk?
DHH: No. You can't really faux hawk long hair like that. I’m actually using serious chemicals.
DAVID B: I just came back from San Francisco. You totally can.
DHH: Alright. [Laughter]
CHUCK: I totally need a picture. [Laughter]
DAVID B: I saw, honest to goodness, I saw a faux hawk comb over. The guy had a bald spot and he had done it up in a faux hawk. It was terrifying.
CHUCK: [Laughs] Is that your pick, David?
DAVID B: Yes, yes. The faux hawk comb over. [Laughs]
CHUCK: Yeah, find us a picture and we'll put it in the show notes.
DAVID B: I should have taken a picture of it. I really should. You want me to do a pick?
CHUCK: Yeah, what are your picks?
DAVID B: Magic Piano for iPad. It's like Guitar Hero, only…
JAMES: For cats.
DAVID B: Only for cats, yeah. More like Tappitty-Tappitty. My wife started playing this while she was in San Francisco. And she’s like, "Oh, this is a great game." And the whole time I would call home every night and she would be looking down instead of looking at the camera the whole time. [Laughter]
DAVID B: I realized that she is playing a game this entire time. And it's like Guitar Hero only that it’s Piano Hero, I guess. And I've been enjoying it. It's a lot of fun. I wish I had a more like intellectual pick. But it's you know, just Magic Piano.
CHUCK: David Brady, our new piano man.
DAVID B: That's right.
CHUCK: Alright. James, what are your picks?
JAMES: So, I've got a couple of technical picks this time. First of all, if you are an object geek, write me and Avdi. Then, you should definitely watch Avdi's new video where he did Lunch and Learn at the Hashrocket office. And he goes through them and breaks down like four different ways to bust up large classes into smaller classes. And what I really love about it is he talks about the pros and cons of both, not really just saying, “This one always wins,” or anything like that. It's like, “Well, here's the upside, here's the downside.” And then there is Avdi's talk and then he gets into a discussion with the Hashrocket group afterwards. And they weigh their pros and cons and the various things that he talked about and situations where they have used them positively and negatively or a bit bomb and stuff. And so, it's really cool stuff. You should definitely go watch that video. And the other one that I liked this week was the new Peepcode Play by Play. I swear, I think I've recommended almost every single one of these. But man! I love those Play by Plays. This one's with Kyle Kneath who is a Github designer. And so, I'm not a designer and it's not really targeted to me and it's still a freaking awesome video because Kyle goes through and shows how he like will mock up putting a new design feature in there and you just have to see this to believe it. Like, for example, he will open up the web inspector and then like change the text on buttons and stuff so that he can screen shot them and have the perfect button that fits the site. But it's like he changed the text to what he needs for the feature. And his Photoshop skills are stellar. And they apply to other things too like I tend to use Acorn. But the way he arranges things in layers, he will take a snap shot of the site and then layer several things on it. He can turn on and off so you see what it's like when this particular feature is in or not in. It's just really cool stuff to see. So, if you want to level up on that using some kind of graphic tools and a web browser in unusual ways, you should check out that video. Those are my picks.
CHUCK: Alright, cool! So, James picked Avdi and Avdi picked DHH. Who's going to pick Josh? I know. Josh, what are your picks?
JOSH: [Laughs] I'm actually going to pick somebody too. This is a coincidence. My pick is Alan Turing. I just realized recently that in about a month, it is the centenary of Alan Turing's birth. And for anybody who's not a real serious geek, you may not know that Alan Turing was a British man. He was born 100 years ago and he pretty much invented the modern field of Computer Science out of his brilliance. And through some very extreme cleverness, built pretty much like the first real computing machine that was used to break the Enigma Code being used by the Germans in World War II and probably took a couple of years off the war effort and saved many thousands of lives. And he was also a gay man who suffered at the hands of British law in that day for it and ended up killing himself over the treatment that he received for that. And so, he is definitely a fascinating character and pretty much everything that I do in my life and many of us do in our lives is a result of his brilliance and contributions. So, I and some friends, figured it's probably kind to have a holiday in his honor. So, if you go to AlanTuringDay.com, you'll see the most minimal website you can imagine right now. But over the next month, it's going to turn into something a little more interesting, I hope. And we had a Github repo up for people who want to contribute to the site and who knows what will happen with this. But I think it's time to give the man his due. So, that's my pick, Alan Turing.
DAVID B: I just want to say, Josh, that is not the most minimal site I can imagine. The most minimal site says, "Hello! You're successfully using Ruby on Rails.” [Laughter]
DAVID B: You can find this page in Public/Index.html.
CHUCK: Yeah. Or the one that it loads up and it doesn't say anything except for the horizontal rule and then underneath it says, “Apache 2.2 syntax, blah…blah…blah.” [Laughter]
CHUCK: I call that the Hack Me Page. [Laughter] JOSH: Okay, well, thanks so much for that. [Chuckles]
CHUCK: Alright, who's next? Is that me?
JAMES: Go for it.
CHUCK: So, my first pick is something that I used for a while and then I kind of forgot I had an account there. And I've picked it up lately because I'm designing courses and designing online training. And incidentally, if you're interested in learning how to build JSON APIs, it's going to be real general and not super Ruby or Rails focused, but just kind of the principles behind it. I'm going to be putting on a live online training in June for that. And then, I'll be selling the video as a digital product. But anyway, so, I've been organizing the curriculum for these different things for the Ruby on Rails Course that I'm putting together for an online training site. And for the CoffeeScript Course, I'm putting the other for another one. And so, I've been doing a lot of mind mapping. And the tool of choice for me is MindMeister. I don't know if you guys have used it. You can actually pay for it and then you get more mind maps and you can also share your mind maps with other people. So, for example, I had a mind map that I had done for Ruby on Rails that kind of gave me an idea of where I could go with this Ruby on Rails course for the training site. And so, I actually shared it with their editor and content guy over there. And then, he could kind of get an idea of what I was thinking about and what some of the areas were that I could go into for Rails. And it's just a really nice tool for that. One other one and I know it's been picked on the show before. But I've actually been sinking a little bit of time into Skyrim. It was funny, I played it for like the half hour or so, just long enough to get out of the first part where you're trying to escape where the dragon's tearing apart the little town at the beginning. And I got done with that and I was like…
CHUCK: Yeah, the very beginning of the game. [Laughs] But anyway, so, I just barely escaped and then I got off. And I didn't play it for a while because it was like, "Yeah, well, whatever." You know, a lot of people really liked this game, but I guess it's just not my kind of thing. Well, I got back in and played for like two hours or so a few nights ago. And it went from that to, "Wow, this is a really cool game." So yeah, go ahead and play Skyrim. I think Laura actually picked that last week though. Anyway, those are my picks. David, what are your picks?
DHH: First, I'd say, actually, I was just writing some code this morning and Textmate 1 is my pick. I've been using that editor since it first came out, I think, in 2004 or 2005, I think 2004. And it's probably one of the only pieces of software that I've had zero interest in updating. I mean, it's one of those things where like a pencil, to me, it's just done. It doesn't need more things bolting on. And it just surprises me how content I can be with a piece of software like an editor which is why I sort of watched and used on as people grew disillusioned with Alan's lack of progress and coming up with a new version. And I was just surprised that I could be so content with a piece of software that apparently so many other people were so discontent about. Anyway, first pick Textmate 1. And second pick, Apple TV. I think that Apple's little black box is just absolutely wonderful. You can bring it with you anywhere, even to a hotel. Most hotels have some sort of DVD player or whatever where you can just plug in your Apple TV instead and all of a sudden, you get access to the best entertainment out there which is, in my mind, TV shows at the moment, Game of Thrones, Mad Men, all that good stuff. I think it's amazing how accessible that the Apple TV has made that stuff on a proper screen, not just watching it on your computer. And I thought I had one more. I forgot. JOSH: David, I just want to say I love the Apple TV too. But they're not just for entertainment. I believe every conference room should have an Apple TV hooked up to the big TV in there so that people can just like bring in their iPads and hook up to it over AirPlay and do presentations and share notes and all that. They're great for that.
DHH: Oh, totally. And I think they're going to be even better in the next version of OS 10 because it's going to have that AirPlay duplicate my screen or whatever that the iPad already has. So then, it's really going to be awesome.
JAMES: That’s cool.
DHH: Alright. That's it.
CHUCK: Alright. Well, to wrap this up, there are a few announcements we need to make. First off, we are doing our Book Club. We are reading Working with Unix Processes by Jesse Storimer. And you can go to WorkingWithUnixProcesses.com and buy the book. If you use the code Book Club, you get $5 off and that goes to support Jesse and all the great work that he did on that book. Really, really cool book. I just finished it last night. Do we have any other announcements?
JAMES: I don’t think so.
CHUCK: Okay. I'm going to put a link up to the JSON training that I'm going to be doing and any other training that I'm going to have going on. And yeah, so let's just …
JOSH: Do we want to plug Parley?
CHUCK: Oh yes, yes. So, the Parley link is still in the right hand sidebar on RubyRogues.com. It will move because I am almost ready to launch the new website that's going to be hosting this and my other podcasts. But in the meantime, if you go to RubyRogues.com and just over in the right sidebar, you can sign up for Ruby Rogues Parley. It's really inexpensive. It's like $10 a year is what we decided. You can go in and do one of the other levels, but you don't get anything extra for that. It's just if you want to support the show more than the $10 a year, but that just goes to help us continue to provide this content. And we add you to a Google group where we've been having discussions about some of the content for the show. Some really amazing stuff has gone on in there, I think so.
JOSH: Yeah. And it's like, if you want to get in on the like pre-discussing the Unix Processes Book and get set up for us to ask questions to Jesse, that's a good way to do it.
CHUCK: Yeah, absolutely. So, go sign up and we'll get you in the list. And other than that, I'm not going to be aournd next week. So, you guys will have to go on without me.
JAMES: It will be hard.