1 00:00:16,120 --> 00:00:17,560 STEVEN G. HARMS: Hi. Good afternoon everyone. 2 00:00:17,600 --> 00:00:20,549 We're starting a little bit late, I think, 3 00:00:20,580 --> 00:00:27,050 because of AV issues. So I think we're gonna have to breeze through. 4 00:00:27,050 --> 00:00:28,541 So you are in the right place if you wanted to hear 5 00:00:28,541 --> 00:00:32,630 about preferring object-orientation to metaprogramming. 6 00:00:32,630 --> 00:00:34,830 My name is Steven Harms, just a brief rundown. 7 00:00:34,830 --> 00:00:36,610 I live in San Francisco like a great many 8 00:00:36,620 --> 00:00:40,210 of you. You can Tweet at me @SGHarms. I'll 9 00:00:40,210 --> 00:00:42,290 also supply an email address if you like to 10 00:00:42,300 --> 00:00:45,140 interact in a slower form of communication. 11 00:00:45,160 --> 00:00:47,700 What I'd like to do is talk to you 12 00:00:47,700 --> 00:00:51,390 about preferring object-orientation to metaprogramming. Now I have to 13 00:00:51,390 --> 00:00:52,540 admit I'm a little bit scared to be up 14 00:00:52,540 --> 00:00:54,990 here, because two years ago I was extolling the 15 00:00:54,990 --> 00:00:58,530 virtues of metaprogramming left and right in New Orleans. 16 00:00:58,530 --> 00:01:01,990 So, well thank you very much. 17 00:01:02,000 --> 00:01:03,999 But I, you know, you can all tell your 18 00:01:04,000 --> 00:01:07,410 significant other that, apparently, one time, a programmer did 19 00:01:07,410 --> 00:01:11,080 admit that he or she was wrong. So I 20 00:01:11,080 --> 00:01:13,811 was wrong. And I hope to light, guide you 21 00:01:13,820 --> 00:01:17,570 on that journey, sitting up here, or, rather, standing 22 00:01:17,570 --> 00:01:19,079 up here and saying you're wrong is a very 23 00:01:19,080 --> 00:01:22,220 interesting experience. But I have been advised that I 24 00:01:22,220 --> 00:01:25,501 should take my fear out of my back pocket 25 00:01:25,501 --> 00:01:28,101 and put it into me. 26 00:01:32,040 --> 00:01:34,370 I would like to say, I love metaprogramming. It's 27 00:01:34,400 --> 00:01:38,000 a fascinating topic. It's rich. It's something very special 28 00:01:38,000 --> 00:01:40,459 to Ruby and I first got exposed to it 29 00:01:40,460 --> 00:01:45,331 at RubyConf 2007, hosted by the, our friend Dr. 30 00:01:45,340 --> 00:01:48,270 Jim Freeze - Jim might be here. I don't 31 00:01:48,270 --> 00:01:48,940 see him. 32 00:01:48,940 --> 00:01:50,760 But I can't remember who it was, but somebody 33 00:01:50,760 --> 00:01:53,320 at lunch showed me this thing here, this thing 34 00:01:53,320 --> 00:01:57,360 on line four, where I- I don't know where 35 00:01:57,360 --> 00:01:58,849 you are, but when I saw that I was 36 00:01:58,849 --> 00:02:01,821 like, this is crazy. What, what language is this? 37 00:02:01,821 --> 00:02:04,240 At the time, I was coming from Perl and, 38 00:02:04,240 --> 00:02:08,089 regrettably, Perl made solving some problems exceedingly painful. 39 00:02:08,100 --> 00:02:11,281 So I was pretty much on, I was undecided 40 00:02:11,281 --> 00:02:13,360 between Python and Ruby, but when I saw that 41 00:02:13,360 --> 00:02:15,760 thing, I was like, whatever language uses that to 42 00:02:15,780 --> 00:02:18,800 do something like define methods, I, I was won 43 00:02:18,800 --> 00:02:21,190 over. 44 00:02:21,190 --> 00:02:23,160 And then I saw something crazy like this, is 45 00:02:23,160 --> 00:02:26,510 that you could create instances and just put methods 46 00:02:26,510 --> 00:02:29,250 only on that instance and not let other classes 47 00:02:29,250 --> 00:02:31,910 have access to it. I was thinking, this is 48 00:02:31,920 --> 00:02:34,560 why my Perl has sucked so bad. The reason 49 00:02:34,560 --> 00:02:36,900 Perl sucks is because Perl sucks and it doesn't 50 00:02:36,900 --> 00:02:39,730 have awesome constructs like this. It is not because 51 00:02:39,730 --> 00:02:44,760 I'm an ignorant, uninformed programmer. It's because Perl sucks. 52 00:02:44,760 --> 00:02:48,920 And if you're looking for something that was absolutely 53 00:02:48,920 --> 00:02:51,360 about to prove to you how bad Perl sucked 54 00:02:51,360 --> 00:02:53,670 and how awesome I was, it was that I 55 00:02:53,680 --> 00:02:57,310 could basically invoke methods that didn't exist, and Ruby 56 00:02:57,310 --> 00:02:59,940 would help me out. It would let me just 57 00:02:59,940 --> 00:03:02,180 keep stringing that noose along so that I could 58 00:03:02,180 --> 00:03:05,460 hang myself good and proper later on. It would 59 00:03:05,460 --> 00:03:07,260 not blow up on me and I could say, 60 00:03:07,260 --> 00:03:08,860 hey, don't blow up, I want you to do 61 00:03:08,860 --> 00:03:13,320 something else. In this case, summon hateful spirits of 62 00:03:13,340 --> 00:03:18,030 the netherworld as inspired by H.P. Lovecraft. 63 00:03:18,030 --> 00:03:20,600 But time passed, and thanks to my tools that 64 00:03:20,600 --> 00:03:22,630 I showed you, the metaprogramming tools, I was able 65 00:03:22,630 --> 00:03:25,480 to build really, really complex software. And I was 66 00:03:25,480 --> 00:03:29,430 so proud of what metaprogramming made possible that I 67 00:03:29,440 --> 00:03:32,110 went to New Orleans in 2011 and told all 68 00:03:32,110 --> 00:03:35,060 of you - some of you - how great 69 00:03:35,060 --> 00:03:37,910 metaprogramming was and what it could provide you. 70 00:03:37,920 --> 00:03:39,700 I had to live with that code for two 71 00:03:39,700 --> 00:03:43,210 years. Which involved me having to refactor it, having 72 00:03:43,210 --> 00:03:45,730 to own it, and some of my opinions might 73 00:03:45,740 --> 00:03:48,570 have changed. So that's what this talk is about, 74 00:03:48,570 --> 00:03:51,230 is how might your opinions change if you are 75 00:03:51,240 --> 00:03:55,320 the maintainer of the heavily metaprogrammed library. 76 00:03:55,320 --> 00:03:59,550 We're gonna be guided by three questions here. 77 00:03:59,550 --> 00:04:02,450 The first question is, when should I use metaprogramming? 78 00:04:02,460 --> 00:04:06,190 The second is, when should I prefer something else? 79 00:04:06,190 --> 00:04:10,910 And if something else, what is that something? 80 00:04:10,920 --> 00:04:15,150 Regrettably, every time you talk about metaprogramming, you have 81 00:04:15,150 --> 00:04:18,428 to define it first. Ruby Rogues number twelve, Ruby 82 00:04:18,440 --> 00:04:21,649 Rogues number eighty, my talk in 2001, you always 83 00:04:21,649 --> 00:04:24,590 have to define the terms, or else you're liable 84 00:04:24,590 --> 00:04:27,001 to get cited and get kicked out of RubyConf 85 00:04:27,040 --> 00:04:29,540 to come. 86 00:04:29,540 --> 00:04:32,700 So my definition - oh, excuse me, wrong button. 87 00:04:32,700 --> 00:04:37,200 My definition, definition is that you're writing code that 88 00:04:37,200 --> 00:04:42,439 redirects passed messages at runtime. Or you're altering the 89 00:04:42,440 --> 00:04:48,600 structures that do the passing at runtime. At runtime. 90 00:04:48,700 --> 00:04:52,411 You see, Ruby is an interpreted language. So there's 91 00:04:52,411 --> 00:04:55,640 really no difference between compile time and execution time. 92 00:04:55,640 --> 00:04:58,270 Everything lives in the space of runtime. But I 93 00:04:58,270 --> 00:05:00,709 would like to ask everyone's indulgence for a moment 94 00:05:00,709 --> 00:05:03,091 to imagine that there is a magical phase right 95 00:05:03,100 --> 00:05:06,139 before runtime called parse time. And parse time is 96 00:05:06,140 --> 00:05:09,300 where your constant tree is established. It's where all 97 00:05:09,300 --> 00:05:12,471 of your libraries are required. And then there's something 98 00:05:12,480 --> 00:05:14,390 else that happens once you enter the main thread 99 00:05:14,390 --> 00:05:15,679 of execution. 100 00:05:15,680 --> 00:05:18,270 It's that main thread part is runtime, the part 101 00:05:18,270 --> 00:05:22,901 that happens before is parse time. 102 00:05:22,901 --> 00:05:27,289 So redirected parse, past messages at run time, providing 103 00:05:27,300 --> 00:05:31,441 and altering those structures at runtime. 104 00:05:31,441 --> 00:05:34,000 That's metaprogramming. If we've all agreed that that's the 105 00:05:34,000 --> 00:05:37,639 standard base of reference, the question that I asked 106 00:05:37,640 --> 00:05:40,381 in 2011 was how will I know that I 107 00:05:40,381 --> 00:05:43,350 should use metaprogramming? And I took that question and 108 00:05:43,360 --> 00:05:45,159 that time to be a reflection on, how do 109 00:05:45,160 --> 00:05:47,530 I know I'm smart enough to use metaprogramming? 110 00:05:47,530 --> 00:05:49,490 And at that time I was feeling pretty damn 111 00:05:49,490 --> 00:05:52,420 smart, and I wanted everyone else to feel that 112 00:05:52,420 --> 00:05:57,860 smart and to jump off that metaprogramming cliff. 113 00:05:57,860 --> 00:06:01,730 I think the question now is, when should I 114 00:06:01,740 --> 00:06:04,670 ever use metaprogramming? And I think I have a 115 00:06:04,670 --> 00:06:07,051 new answer for that one. I think the answer 116 00:06:07,060 --> 00:06:08,160 is never. 117 00:06:08,160 --> 00:06:14,489 Oh, all right, all right, I'm gonna hedge my 118 00:06:14,489 --> 00:06:17,640 bets. Practically never. On the cons- in the contrary 119 00:06:17,660 --> 00:06:19,020 case, the question should be, well, when should I 120 00:06:19,020 --> 00:06:26,020 use something else? Always. Eh, practically always. 121 00:06:26,320 --> 00:06:28,830 The trouble I said in 2011 was that we 122 00:06:28,830 --> 00:06:31,581 had unclear guidance about how to move forward in 123 00:06:31,581 --> 00:06:33,039 metaprogramming. It tended to be something that was kind 124 00:06:33,040 --> 00:06:35,280 of showed by people at conferences and something that 125 00:06:35,280 --> 00:06:37,600 was kind of obliquely referred to. But it was 126 00:06:37,600 --> 00:06:40,121 never really explained as, here's a technique. Here's how 127 00:06:40,121 --> 00:06:41,870 you can grow better in it. Here's how you 128 00:06:41,870 --> 00:06:43,649 can learn more about it. 129 00:06:43,649 --> 00:06:46,911 And there's a good reason for that. I'll quote 130 00:06:46,920 --> 00:06:50,379 Tim Connor, who I also quoted in 2011, was 131 00:06:50,380 --> 00:06:52,641 the first rule of metaprogramming is you don't talk 132 00:06:52,641 --> 00:06:55,409 about it, because you'll get people to use it. 133 00:06:55,409 --> 00:06:56,381 Accurate. 134 00:06:56,381 --> 00:07:02,139 And then the second rule is that, when you 135 00:07:02,140 --> 00:07:05,161 do introduce it, you introduce a level of complexity 136 00:07:05,161 --> 00:07:10,530 that most people, due to just unfamiliarity, will not 137 00:07:10,530 --> 00:07:13,639 understand how to parse. And now here's the sentence 138 00:07:13,660 --> 00:07:16,981 that kills me, is that unfortunately, you cannot simply, 139 00:07:16,981 --> 00:07:20,179 sorry, that was a typo, be told not to 140 00:07:20,180 --> 00:07:22,550 metaprogram. You must see it for yourself. 141 00:07:22,550 --> 00:07:24,471 That's the part I take issue with. I can 142 00:07:24,480 --> 00:07:26,869 show you, I believe, in the remainder of this 143 00:07:26,880 --> 00:07:29,801 presentation, of why you should not use metaprogramming. In 144 00:07:29,801 --> 00:07:32,620 short, I want you to say no to metaprogramming. 145 00:07:32,620 --> 00:07:35,110 In fact, if you're from the Pacific Northwest, I 146 00:07:35,110 --> 00:07:39,549 want you to say cacao to metaprogramming. 147 00:07:39,549 --> 00:07:43,170 Now, I'm gonna take a bit of a, a 148 00:07:43,180 --> 00:07:45,710 side long step here, and I'm going to kind 149 00:07:45,720 --> 00:07:48,181 of fall in the spirits, follow in the spirit 150 00:07:48,181 --> 00:07:51,288 of the philosophers Gilles and Guattari. I'm going to 151 00:07:51,288 --> 00:07:53,780 take apart the term metaprogramming itself. It is a 152 00:07:53,780 --> 00:07:55,930 bad term. 153 00:07:55,930 --> 00:07:58,760 First of all, it's hard to define. Every speaker, 154 00:07:58,760 --> 00:08:00,941 every time they use the word metaprogramming, has to 155 00:08:00,941 --> 00:08:02,979 come in and define what they mean in order 156 00:08:02,980 --> 00:08:05,941 to try to establish some sort of consensual basis. 157 00:08:05,941 --> 00:08:08,220 If the term has to be renegotiated all the 158 00:08:08,220 --> 00:08:11,599 time, what is its value? Nothing. 159 00:08:11,600 --> 00:08:14,730 Secondarily, I, I have a theory that it gets 160 00:08:14,730 --> 00:08:16,470 by a lot of time because it has this 161 00:08:16,480 --> 00:08:20,930 really awesome Greek prefix at the beginning of meta. 162 00:08:20,930 --> 00:08:23,350 When I was that young programmer in Austin, somebody 163 00:08:23,360 --> 00:08:25,930 showed me metaprogramming, and I thought, my gosh I 164 00:08:25,930 --> 00:08:28,920 am so stupid. I am so ignorant. I don't 165 00:08:28,920 --> 00:08:31,720 know what metaprogramming is. I, I, I missed that 166 00:08:31,720 --> 00:08:34,320 class in the CS curriculum. I don't know what 167 00:08:34,320 --> 00:08:35,890 it's about. 168 00:08:35,900 --> 00:08:39,421 And, and having dug into it, I've dug into 169 00:08:39,421 --> 00:08:40,919 it and I understand it now and it's just 170 00:08:40,919 --> 00:08:44,590 a bad idea. And it skates by because it 171 00:08:44,590 --> 00:08:46,950 has this cool topic. Write a CFP, include the 172 00:08:46,960 --> 00:08:53,960 word metaprogramming, you'll get a speaker slot. I know. 173 00:08:55,500 --> 00:08:58,250 It's a bad term. But it's also a bad 174 00:08:58,250 --> 00:09:03,519 technique. Recall, well, foremost, let me say that it 175 00:09:03,520 --> 00:09:06,000 has a bad conceptual framework, and I will demonstrate 176 00:09:06,000 --> 00:09:09,591 this. The code itself, Ruby will tell you don't 177 00:09:09,600 --> 00:09:12,019 do this. You can choose to ignore it, like 178 00:09:12,020 --> 00:09:14,431 me, but Ruby will try to help you avoid 179 00:09:14,431 --> 00:09:17,379 this trap. And lastly, I want to talk a 180 00:09:17,380 --> 00:09:22,851 little bit about normative social standards visa vis metaprogramming. 181 00:09:22,860 --> 00:09:26,020 So recall that when we talked about my definition 182 00:09:26,020 --> 00:09:29,200 of metaprogramming, is we focused relentlessly on this concept 183 00:09:29,200 --> 00:09:31,911 of runtime. And here's the interesting this is that 184 00:09:31,920 --> 00:09:36,269 runtime specifies a temper, a temporarily to these clauses, 185 00:09:36,269 --> 00:09:39,440 but here's the thing. Check out the verb - 186 00:09:39,440 --> 00:09:40,851 alters, redirects. 187 00:09:40,860 --> 00:09:44,980 These are verbs that express surprise. These are verbs 188 00:09:44,980 --> 00:09:50,500 that express something not doing what was expected. Metaprogramming 189 00:09:50,500 --> 00:09:56,610 is writing code that willfully does something that's surprising 190 00:09:56,610 --> 00:10:01,910 and contrary to convention. I think there's a special 191 00:10:01,910 --> 00:10:04,970 word for that, right. You write code sometimes and 192 00:10:04,970 --> 00:10:10,160 it does something that you don't expect, right. 193 00:10:10,160 --> 00:10:15,499 That one. Yeah. Metaprogramming, in effect, is engineering bugs 194 00:10:15,500 --> 00:10:20,250 that do the right thing. Not only that, but 195 00:10:20,260 --> 00:10:22,690 they do it adventitiously. I'm including this, not because 196 00:10:22,690 --> 00:10:23,990 I'm talking down to you, but I do realize 197 00:10:24,000 --> 00:10:26,111 English isn't the first language of some people in 198 00:10:26,120 --> 00:10:26,829 the audience. 199 00:10:26,829 --> 00:10:30,572 Adventitious - coming from another source. Not inherent or 200 00:10:30,580 --> 00:10:33,489 innate. If your code does not innately do the 201 00:10:33,489 --> 00:10:36,230 right thing, that means that it's more likely to 202 00:10:36,240 --> 00:10:39,260 do the wrong thing. So you are quite literally 203 00:10:39,260 --> 00:10:44,361 putting yourself in a position of possible accident. 204 00:10:44,361 --> 00:10:49,210 Or, in short, metaprogramming is a series of aberrations 205 00:10:49,210 --> 00:10:52,010 that just happen to produce the right output most 206 00:10:52,020 --> 00:10:53,950 of the time. Or, at least, as much as 207 00:10:53,950 --> 00:10:55,760 your test coverage says that they produce the right 208 00:10:55,760 --> 00:10:57,070 output. 209 00:10:57,080 --> 00:11:02,259 Missing image. Again, another form of bug. It's a 210 00:11:02,260 --> 00:11:05,271 reminder of that when you think things are OK, 211 00:11:05,280 --> 00:11:08,460 they are, in fact, not OK. So let's talk 212 00:11:08,460 --> 00:11:13,470 about how a, whoa, it's a broken image. Well, 213 00:11:13,470 --> 00:11:14,970 that's a, that's a new bug for me too. 214 00:11:14,970 --> 00:11:19,760 Let's see. OK. Well, I'm sorry. I can't show 215 00:11:19,760 --> 00:11:21,549 you this one cause the image isn't on this 216 00:11:21,580 --> 00:11:22,450 asset. 217 00:11:22,450 --> 00:11:23,851 But the point being is that if you try 218 00:11:23,860 --> 00:11:26,610 to use a heavily metaprogrammed library, you know that 219 00:11:26,610 --> 00:11:28,400 thing in IRB or Pry where you can do 220 00:11:28,400 --> 00:11:32,300 tab tab to complete a method name? Metaprogrammed methods 221 00:11:32,300 --> 00:11:34,139 do not appear as part of that. That is 222 00:11:34,140 --> 00:11:36,911 Ruby trying to tell you, hey, I don't know 223 00:11:36,920 --> 00:11:39,610 what you're talking about, and the conventions and expectations 224 00:11:39,610 --> 00:11:42,199 that I have, you are not following. If you 225 00:11:42,200 --> 00:11:46,630 choose not to follow those conventions, it's on you. 226 00:11:46,630 --> 00:11:48,391 And because it's on you, you have the obligation 227 00:11:48,400 --> 00:11:51,170 to write extensive amounts of test coverage. In this 228 00:11:51,170 --> 00:11:52,859 case, I had to write one thousand six hundred 229 00:11:52,860 --> 00:11:55,310 and forty-six assertions to feel like my library was 230 00:11:55,310 --> 00:11:58,831 doing the right thing, whereas if I had chosen 231 00:11:58,840 --> 00:12:03,009 smaller, more constrained scopes of my objects, I would 232 00:12:03,009 --> 00:12:05,370 have felt more comfortable having fewer of them. 233 00:12:05,370 --> 00:12:07,311 As it stands, I had to write near two 234 00:12:07,320 --> 00:12:11,169 thous- well, all right, near sixteen hundred assertions to 235 00:12:11,180 --> 00:12:13,531 feel comfortable in my code. You should never have 236 00:12:13,540 --> 00:12:15,559 to write that many assertions to feel comfortable in 237 00:12:15,560 --> 00:12:18,760 your code. 238 00:12:18,760 --> 00:12:20,231 I'd also like to point out that, as I 239 00:12:20,240 --> 00:12:24,709 showed in the earlier sample, when you have metaprogrammed 240 00:12:24,709 --> 00:12:28,760 code hinging on method missing, if something blows up, 241 00:12:28,760 --> 00:12:30,070 you're catching the method missing error. Instead of your 242 00:12:30,070 --> 00:12:34,050 error bubbling up to something saying hey, you messed 243 00:12:34,050 --> 00:12:36,271 up, you need to backwar, backtrack this and fix 244 00:12:36,280 --> 00:12:39,309 it. Instead now you bear the responsibility for handling 245 00:12:39,309 --> 00:12:41,691 how method missing works. 246 00:12:41,700 --> 00:12:44,160 And because of that, you're taking on an additional 247 00:12:44,180 --> 00:12:47,690 cognitive burden, and you're taking on an additional - 248 00:12:47,690 --> 00:12:51,769 that you just should not have to take on. 249 00:12:51,769 --> 00:12:54,711 I spoke about social conventions. You don't have to 250 00:12:54,720 --> 00:12:56,369 listen to me and you don't necessarily have to 251 00:12:56,369 --> 00:12:57,870 listen to the code, but you could listen to 252 00:12:57,880 --> 00:13:00,611 some dude on Twitter, which is what a lot 253 00:13:00,620 --> 00:13:04,509 of people do apparently. Joshua Timberman said, well actually, 254 00:13:04,509 --> 00:13:08,020 he didn't say, he metasaid, somebody- he metaTweeted that 255 00:13:08,020 --> 00:13:11,101 someone said that his amount of disdain for Ruby 256 00:13:11,101 --> 00:13:13,689 projects is directly proportional to the amount of magic 257 00:13:13,700 --> 00:13:15,551 it contains. 258 00:13:15,551 --> 00:13:21,680 Metaprogramming and intercepting method missing, bolting on behavior onto 259 00:13:21,680 --> 00:13:24,930 instances. All of these things, in sum total, account 260 00:13:24,940 --> 00:13:26,550 for magic. 261 00:13:26,550 --> 00:13:28,699 So, what I would like to do is put 262 00:13:28,700 --> 00:13:31,101 an end to quote metaprogramming. What I would like 263 00:13:31,101 --> 00:13:33,280 for us to do is to retire the term, 264 00:13:33,280 --> 00:13:36,199 retire the talks, and move on. I would like 265 00:13:36,200 --> 00:13:38,841 for this to be, you know, apologies to Francis 266 00:13:38,841 --> 00:13:41,490 Fukiyama, I'd like to be the, the last man 267 00:13:41,490 --> 00:13:45,150 standing on the topic of metaprogramming. I think we 268 00:13:45,150 --> 00:13:47,239 all need to move on and let's just close 269 00:13:47,240 --> 00:13:49,331 the door. 270 00:13:49,340 --> 00:13:51,200 Now the question is, if you're going to say 271 00:13:51,200 --> 00:13:53,429 that something is bad, what do you recommend you 272 00:13:53,440 --> 00:13:56,131 replace it with? So what I would like to 273 00:13:56,140 --> 00:14:00,070 do is talk about the replacement to metaprogramming. The 274 00:14:00,070 --> 00:14:03,481 replacement to metaprogramming would, of course, be something like 275 00:14:03,481 --> 00:14:07,230 anti-metaprogramming. It would be taking out all of that 276 00:14:07,230 --> 00:14:09,720 magic. It would be taking out all of your 277 00:14:09,720 --> 00:14:13,510 method missing calls, your conts get calls. It would 278 00:14:13,520 --> 00:14:16,200 be taking out all those instance evals, class evals. 279 00:14:16,220 --> 00:14:18,310 It would be taking out all these weird clojure 280 00:14:18,310 --> 00:14:21,319 things. 281 00:14:21,320 --> 00:14:24,320 Anti-metaprogramming code would be deducible from the parse time 282 00:14:24,320 --> 00:14:26,091 state, that is to say, you could look at 283 00:14:26,100 --> 00:14:28,459 the code at rest and figure out what's going 284 00:14:28,460 --> 00:14:32,231 on. I alluded earlier that I considered metaprogramming often 285 00:14:32,231 --> 00:14:34,610 to be a type of bug. Often to understand 286 00:14:34,620 --> 00:14:36,930 the state of the application at the time, you 287 00:14:36,930 --> 00:14:38,699 wind up having to use debugging tools. 288 00:14:38,700 --> 00:14:40,411 As you're saying, well why is this not doing 289 00:14:40,420 --> 00:14:42,689 what I expect? What do you have to do, 290 00:14:42,689 --> 00:14:45,031 you have to drop in a Pry binding or 291 00:14:45,040 --> 00:14:47,050 you have to put in ByeBug or a debugger 292 00:14:47,050 --> 00:14:49,300 statement just to figure out what's going on. And 293 00:14:49,300 --> 00:14:51,699 the reason is is because you're doing weird stuff 294 00:14:51,700 --> 00:14:55,310 at runtime. Don't do it. 295 00:14:55,310 --> 00:14:59,670 I also believe that code, anti-metaprogramming code, also known 296 00:14:59,670 --> 00:15:03,310 as good code, demonstrates its reason and its purpose 297 00:15:03,320 --> 00:15:08,190 in itself. That is to say, it's obvious. So 298 00:15:08,190 --> 00:15:10,341 let's take a look at some anti-patterns that I 299 00:15:10,341 --> 00:15:13,630 implemented around metaprogramming. 300 00:15:13,640 --> 00:15:16,549 First one - def - oh man, that's really 301 00:15:16,549 --> 00:15:21,071 unfortunate. Hmm. Let's see here, what can I do 302 00:15:21,080 --> 00:15:24,100 about this? I want to know why it's showing 303 00:15:24,100 --> 00:15:30,330 up on my screen. Is that? Is it? I 304 00:15:30,400 --> 00:15:36,939 don't know. OK. Yes! 305 00:15:36,939 --> 00:15:40,161 AUDIENCE: Yay! 306 00:15:40,161 --> 00:15:44,100 S.G.H.: Thank you. Thank you all. Whew. Yeah, master 307 00:15:44,100 --> 00:15:47,999 debugger back here. Thank you. Wow, OK. Thanks so 308 00:15:48,000 --> 00:15:50,861 much. That was really helpful. Go team. Obviously some 309 00:15:50,861 --> 00:15:53,309 garbage collectors in the audience. 310 00:15:53,309 --> 00:15:56,031 I would like to point out define method. Define 311 00:15:56,040 --> 00:16:00,090 method - Rubyists new to, Rubyists who are new 312 00:16:00,090 --> 00:16:04,330 to language may be surprised to find out that 313 00:16:04,330 --> 00:16:09,369 you can define methods based on taking out terms 314 00:16:09,380 --> 00:16:12,440 and then, and creating them dynamically at runtime. Don't 315 00:16:12,440 --> 00:16:15,041 do this. This is bad. And you may say, 316 00:16:15,041 --> 00:16:16,489 oh well, this isn't so bad, and you have 317 00:16:16,489 --> 00:16:18,341 this thing called prefix. You have an inner and 318 00:16:18,341 --> 00:16:20,729 an outer. I get what's going on here. 319 00:16:20,740 --> 00:16:22,130 But the trouble you're gonna have is that it's 320 00:16:22,130 --> 00:16:24,271 not grep-able. And by grep I mean you can 321 00:16:24,280 --> 00:16:26,330 use Ack or Rack or some sort of search 322 00:16:26,330 --> 00:16:28,520 or, through your code. If you're looking for the 323 00:16:28,520 --> 00:16:33,150 method that's called tear_down_the_pop_singer, you're not gonna find it, 324 00:16:33,150 --> 00:16:36,739 because it's somehow being fabricated at runtime. You basically 325 00:16:36,760 --> 00:16:40,920 made your code opaque to other introspective tools. Don't 326 00:16:40,920 --> 00:16:43,031 do that. It's so much better just to write 327 00:16:43,040 --> 00:16:43,759 it out. 328 00:16:43,760 --> 00:16:45,731 And if you're complaining about writing it out, get 329 00:16:45,740 --> 00:16:49,370 a better editor. Because, really, your editor should be 330 00:16:49,370 --> 00:16:50,769 able to take care of this amount of pain 331 00:16:50,769 --> 00:16:53,810 for you. 332 00:16:53,810 --> 00:16:59,220 Again, it has low grepability and it has very 333 00:16:59,220 --> 00:17:02,941 poor graspability. An alternative I propose is just to 334 00:17:02,941 --> 00:17:05,980 use plain old, good old def, right. Here it 335 00:17:05,980 --> 00:17:09,648 is. Where is tear_down_the_pop_singer defined? Right there. Or excuse 336 00:17:09,660 --> 00:17:12,270 me. Right, right there. Yeah. 337 00:17:12,270 --> 00:17:15,961 The ability to resolve problems is so much easier 338 00:17:15,961 --> 00:17:19,749 when you have this available to you. 339 00:17:19,760 --> 00:17:21,550 I'd also like to talk about another anti-pattern that 340 00:17:21,550 --> 00:17:25,961 I've seen recently discussed is the junk drawer module. 341 00:17:25,961 --> 00:17:28,909 Now if you took my previous recommendation that you 342 00:17:28,940 --> 00:17:30,960 actually define your methods, you may say, well I've 343 00:17:30,960 --> 00:17:33,809 created a large class. I don't like that. So 344 00:17:33,809 --> 00:17:35,091 what I'm going to proceed to do is I'm 345 00:17:35,100 --> 00:17:39,100 going to bubble that out into a module and 346 00:17:39,100 --> 00:17:42,710 then I'm gonna include that module into the class. 347 00:17:42,710 --> 00:17:43,919 Don't do this. 348 00:17:43,920 --> 00:17:47,391 This is a classic bad anti-pattern. Because what you've 349 00:17:47,400 --> 00:17:49,900 basically done is you've created a name space that 350 00:17:49,900 --> 00:17:52,900 has absolutely no purpose for its existence. It is 351 00:17:52,900 --> 00:17:55,750 important that we, as programmers, when communicating with other 352 00:17:55,750 --> 00:17:58,580 programmers who will read our code and not our 353 00:17:58,580 --> 00:18:01,750 comments, we need to be able to understand what 354 00:18:01,750 --> 00:18:03,980 is going on in this module. What is the 355 00:18:03,980 --> 00:18:08,060 relationship? Why is raise_the_roof with tear_down_the_pop_star? There is no 356 00:18:08,060 --> 00:18:12,460 good reason. We have no intentionality behind that module. 357 00:18:12,460 --> 00:18:14,950 And as a result of it, our class and 358 00:18:14,960 --> 00:18:17,330 our module name will be entirely opaque to any 359 00:18:17,340 --> 00:18:20,460 other programmer who comes along. 360 00:18:20,460 --> 00:18:26,909 Again, it's obvious, moderately, because it's grepable. But the 361 00:18:26,909 --> 00:18:29,221 graspability is it is poor, and as you add 362 00:18:29,221 --> 00:18:33,019 additional modules, that graspability will go down precipitously. 363 00:18:33,020 --> 00:18:40,020 So don't create junk drawer mixins using Ruby's modules. 364 00:18:40,080 --> 00:18:42,019 I think Sarah may have brought this up recently. 365 00:18:42,020 --> 00:18:45,131 She said, you know, modules may solve the size. 366 00:18:45,140 --> 00:18:47,100 You've got fewer lines of code. But you've done 367 00:18:47,100 --> 00:18:49,669 nothing to illuminate, to open the mind of a 368 00:18:49,669 --> 00:18:53,760 programmer who's coming along to this particular bit of 369 00:18:53,760 --> 00:18:55,101 code. 370 00:18:55,101 --> 00:18:58,110 You could get slightly better. What if you change 371 00:18:58,110 --> 00:19:01,249 those mixin names and gave them something like, some 372 00:19:01,260 --> 00:19:04,321 hint of what they are. But really, you're not 373 00:19:04,321 --> 00:19:06,509 getting much for that level. You still have the 374 00:19:06,509 --> 00:19:11,821 greppability. Moderate graspability. But it's trending down. 375 00:19:11,821 --> 00:19:14,269 Here's a nifty pattern that totally sucks. I did 376 00:19:14,300 --> 00:19:16,111 this one heavily and I'm so embarrassed to show 377 00:19:16,111 --> 00:19:19,510 it. I'm gonna show it right now. 378 00:19:19,510 --> 00:19:22,870 What would happen if, instead of actually creating modules, 379 00:19:22,870 --> 00:19:27,370 you decided to create anonymous modules? Wow. You just 380 00:19:27,380 --> 00:19:31,330 completely hung yourself. That was awesome. And the reason 381 00:19:31,330 --> 00:19:34,040 you've hanged yourself is because, look, you get this 382 00:19:34,040 --> 00:19:36,999 really nice thing by looking at Ruby's ancestor chain. 383 00:19:37,020 --> 00:19:39,831 Cause you can ask an object, or rather, ask 384 00:19:39,840 --> 00:19:43,029 an object's class what the inheritance chain of it, 385 00:19:43,029 --> 00:19:44,111 of it is. 386 00:19:44,120 --> 00:19:46,429 We'd say, where'd you get methods? Where do you 387 00:19:46,429 --> 00:19:49,891 get properties? So I can see class, method deffer, 388 00:19:49,900 --> 00:19:52,890 gets modules from pop_singer_moves and housing_moves and object and 389 00:19:52,890 --> 00:19:56,260 kernel and basic object. That's great. Guess what? When 390 00:19:56,260 --> 00:20:00,640 you use anonymous modules, you get none of that. 391 00:20:00,640 --> 00:20:03,240 So congratulations. You got to use a really, really 392 00:20:03,240 --> 00:20:06,769 cool stylistic invocation that made your code more opaque. 393 00:20:06,780 --> 00:20:08,221 That one hurt. 394 00:20:08,221 --> 00:20:11,830 So, again, there is really no hope at this 395 00:20:11,830 --> 00:20:16,100 point. You've really, really shot yourself in your foot. 396 00:20:16,100 --> 00:20:18,690 Here's another anti-pattern that I completely committed. How about 397 00:20:18,690 --> 00:20:21,320 this one? What if you wanted to make a 398 00:20:21,320 --> 00:20:25,110 class that's including a module do something crazy when 399 00:20:25,110 --> 00:20:28,040 it included that module? Wouldn't that be completely opaque? 400 00:20:28,040 --> 00:20:30,200 Wouldn't that be impossible to understand? yes. 401 00:20:30,200 --> 00:20:36,080 Look at this. This is, this is humiliating. You 402 00:20:36,080 --> 00:20:38,440 may not be aware that module implements a, a 403 00:20:38,440 --> 00:20:41,580 call-back method, so that when you include a module, 404 00:20:41,580 --> 00:20:44,480 magic happens. And what if, in that silent bit 405 00:20:44,480 --> 00:20:47,160 of magic, you decided to do magic back on 406 00:20:47,160 --> 00:20:50,470 the thing that included the module? 407 00:20:50,500 --> 00:20:51,970 This is just pure insanity. I don't even know 408 00:20:51,970 --> 00:20:54,769 what I was thinking. I, I don't do drugs, 409 00:20:54,769 --> 00:20:57,941 but I don't know what I was thinking. I, 410 00:20:57,941 --> 00:20:59,730 I can kind of see, like, a bit of 411 00:20:59,740 --> 00:21:01,810 nobility in here. There's a hint of the desire 412 00:21:01,810 --> 00:21:05,300 to want to invert dependencies, but if you choose 413 00:21:05,300 --> 00:21:07,830 to invert a dependency, which we'll talk about in 414 00:21:07,830 --> 00:21:10,050 just a moment, there are many more obvious ways 415 00:21:10,060 --> 00:21:12,090 of doing it. So don't do this. 416 00:21:12,090 --> 00:21:17,490 So, again, low greppability, abandon all hope. Low graspability. 417 00:21:17,500 --> 00:21:20,480 Abandon all hope. Do not do this. 418 00:21:20,480 --> 00:21:22,490 Here's an interesting pattern. Here's where things start getting 419 00:21:22,490 --> 00:21:24,519 a little bit better. What if you chose to 420 00:21:24,520 --> 00:21:28,120 use the strategy pattern to apply behavior to the 421 00:21:28,140 --> 00:21:32,581 inverted class? So let's take a look at this. 422 00:21:32,581 --> 00:21:35,580 So what if I decided to put those housing 423 00:21:35,580 --> 00:21:38,740 moves in a module that I'm gonna call a 424 00:21:38,740 --> 00:21:41,000 strategy? Now I realize someone's gonna take me to 425 00:21:41,000 --> 00:21:43,940 task on Twitter and say, you're dumb. You don't 426 00:21:43,940 --> 00:21:46,430 understand what the strategy pattern's about. It's not modules, 427 00:21:46,440 --> 00:21:48,019 it's classes. OK, I get it. 428 00:21:48,020 --> 00:21:49,400 But for the sake of this argument, let's kind 429 00:21:49,400 --> 00:21:53,300 of keep with the idea that what, what is 430 00:21:53,300 --> 00:21:55,851 happening in these strategies is that I've basically given 431 00:21:55,860 --> 00:21:59,429 this mixin a meaningful name. I've said, this mixin 432 00:21:59,429 --> 00:22:01,631 isn't just a mixin of some random mod- rad- 433 00:22:01,640 --> 00:22:04,130 random methods that you want to throw into your 434 00:22:04,130 --> 00:22:06,549 class. What I'm saying is that there's an intention 435 00:22:06,549 --> 00:22:08,650 behind it. It's that if you're interested in housing 436 00:22:08,650 --> 00:22:11,231 moves, you're going to have some relationship with this 437 00:22:11,240 --> 00:22:13,220 particular strategy. 438 00:22:13,240 --> 00:22:15,960 So here's how I chose to invert that dependency. 439 00:22:15,960 --> 00:22:18,320 Is what happens is that when you create a 440 00:22:18,320 --> 00:22:23,860 method deffer class, it then proceeds to instantiate a 441 00:22:23,860 --> 00:22:30,860 class called apply_core_strategies, passing itself. The apply_core_strategies then looks 442 00:22:30,860 --> 00:22:35,179 at the essential strategies, intelligible for the next programmer, 443 00:22:35,180 --> 00:22:39,131 of housing_move strategy and pop_movesto_strategy, then it proceeds to 444 00:22:39,131 --> 00:22:42,560 bolt those on, on the calling class. 445 00:22:42,560 --> 00:22:44,279 So I feel like, at this place, we're actually 446 00:22:44,280 --> 00:22:49,581 getting a hint of the, of, we're starting to 447 00:22:49,581 --> 00:22:52,200 tease apart some of the metaprogramming. We're starting to 448 00:22:52,200 --> 00:22:57,220 create small, tiny classes that bear responsibility for certain 449 00:22:57,220 --> 00:23:01,350 tasks of thinking. And I can definitely say the 450 00:23:01,350 --> 00:23:04,360 woman who taught me to start thinking this terms 451 00:23:04,360 --> 00:23:07,759 was Sandy Metts. So I can't say enough about 452 00:23:07,760 --> 00:23:10,260 how she dug me out of my conceptual bad 453 00:23:10,260 --> 00:23:15,331 spot by introducing me to some of these ideas. 454 00:23:15,340 --> 00:23:19,220 Again, the obviousness is moving, is moving upward. The 455 00:23:19,220 --> 00:23:21,159 reason is is that we can always take a 456 00:23:21,160 --> 00:23:22,611 look, you say oh well he implemented this method 457 00:23:22,620 --> 00:23:25,210 poorly or this method poorly, or this strategy is 458 00:23:25,210 --> 00:23:27,549 poorly named, or why are we doing this with 459 00:23:27,560 --> 00:23:29,871 modules? Why don't we use classes so that they 460 00:23:29,871 --> 00:23:32,000 can have a meaningful state? We're trending in a 461 00:23:32,000 --> 00:23:35,570 good direction. We're trending out of opaqueness and difficulty 462 00:23:35,570 --> 00:23:38,120 that we normally associate with metaprogramming, and we're moving 463 00:23:38,120 --> 00:23:41,430 to something that's more deducable, that has smaller scope 464 00:23:41,430 --> 00:23:44,800 that's greppable. 465 00:23:44,800 --> 00:23:48,960 It's also more graspable. Again, fewer lines of code, 466 00:23:48,960 --> 00:23:53,330 higher graspability. that's it. 467 00:23:53,340 --> 00:23:56,980 On the topic of good O-O, I, I don't 468 00:23:56,980 --> 00:23:58,950 have to say Sandy taught me everything I can 469 00:23:58,950 --> 00:24:02,649 stand to know on the topic. The heart of 470 00:24:02,649 --> 00:24:07,870 what makes metaprogramming so bad is that it will 471 00:24:07,880 --> 00:24:11,380 pry- that it puts a very heavy cognitive burden 472 00:24:11,380 --> 00:24:13,650 on the developer. And what I like to say 473 00:24:13,650 --> 00:24:16,061 is that it puts a mind of god burden 474 00:24:16,061 --> 00:24:17,509 on the developer. 475 00:24:17,520 --> 00:24:21,431 Specifically, if you look at metaprogramming techniques that break 476 00:24:21,440 --> 00:24:24,789 object incapsulation, you can actually start to see that 477 00:24:24,789 --> 00:24:28,691 metaprogramming is the last refuge of the procedural programmer. 478 00:24:28,700 --> 00:24:30,899 You have to hold in your mind all of 479 00:24:30,900 --> 00:24:34,770 the possible methods and all of the possible variables 480 00:24:34,770 --> 00:24:36,671 that could be called and all the possible code 481 00:24:36,680 --> 00:24:37,580 paths. 482 00:24:37,580 --> 00:24:40,870 If you're saying no, Ruby, don't do your default 483 00:24:40,870 --> 00:24:44,060 blow-up behavior on Method Missing, you're saying, I'll take 484 00:24:44,060 --> 00:24:48,019 that responsibility on. If you're cracking over someone else's 485 00:24:48,020 --> 00:24:53,630 class, you're saying, don't worry, thread class, I'll take 486 00:24:53,630 --> 00:24:56,630 responsibility in making sure that all your interfaces always 487 00:24:56,640 --> 00:24:59,591 work in all the possible code. 488 00:24:59,600 --> 00:25:01,169 And if you basically say, oh I need to 489 00:25:01,169 --> 00:25:03,910 define core methods within the Ruby language by defining 490 00:25:03,960 --> 00:25:06,200 a kernel method, what you're saying is, don't worry 491 00:25:06,220 --> 00:25:08,511 Ruby, I got you on this one. You are 492 00:25:08,511 --> 00:25:12,669 deficient, I know better. Am I really ever gonna 493 00:25:12,669 --> 00:25:14,890 say that to Matz? 494 00:25:14,890 --> 00:25:17,900 No. I'm not. 495 00:25:17,900 --> 00:25:20,931 Loveable angry panda Rein Henrichs has this pretty, pretty 496 00:25:20,940 --> 00:25:23,690 succinctly said, is if you can go around monkeying 497 00:25:23,690 --> 00:25:27,600 with the core object class or the core fundaments 498 00:25:27,600 --> 00:25:31,410 of the Ruby universe, he and his loved ones 499 00:25:31,420 --> 00:25:35,300 should be under no obligation to maintain your level 500 00:25:35,300 --> 00:25:37,730 of insanity. 501 00:25:37,730 --> 00:25:41,739 In fact, what I love about RubyConf is that, 502 00:25:41,740 --> 00:25:43,240 as you write your talk, you write it in 503 00:25:43,260 --> 00:25:44,331 a vacuum. Then all of the sudden you come 504 00:25:44,340 --> 00:25:46,950 into RubyConf and you pick up these pneumatic currents 505 00:25:46,950 --> 00:25:48,850 that are floating about. And what I've seen in 506 00:25:48,850 --> 00:25:52,960 a number of talks, particular yesterday, was Ruby is 507 00:25:52,980 --> 00:25:55,980 maturing. And as a result of it, we now 508 00:25:55,980 --> 00:25:58,909 have a nice variety of gems where people have 509 00:25:58,909 --> 00:26:02,851 shared their solutions to famous problems that other developers 510 00:26:02,860 --> 00:26:05,019 might encounter. 511 00:26:05,020 --> 00:26:07,310 But when you metaprogram, you make it so that 512 00:26:07,310 --> 00:26:12,221 your code can't interact predictably with other peoples' libraries. 513 00:26:12,221 --> 00:26:15,870 Jason Clark talked about extending gems. He's talking about 514 00:26:15,870 --> 00:26:19,320 problems that he had at New Relic with other 515 00:26:19,320 --> 00:26:23,440 developers stomping on his name space. I mean, these 516 00:26:23,440 --> 00:26:25,460 are developers who sit, you know, in San Francisco, 517 00:26:25,480 --> 00:26:27,429 so it's not a very big place. 518 00:26:27,429 --> 00:26:29,871 So he could see these developers every day and 519 00:26:29,880 --> 00:26:32,500 they still managed to step on each others' toes. 520 00:26:32,500 --> 00:26:36,140 What happens in the case that your gem does 521 00:26:36,140 --> 00:26:40,029 something where it overrides some poor kernel functionality, or 522 00:26:40,029 --> 00:26:43,581 it overrides the core functionality of thread or module 523 00:26:43,581 --> 00:26:46,669 or object? Your mind of god is going to 524 00:26:46,669 --> 00:26:49,150 be put in direct contention with someone else's mind 525 00:26:49,150 --> 00:26:52,111 of god, and I'm not sure how that ends, 526 00:26:52,120 --> 00:26:53,860 depending on your theology, but I'm pretty sure it's 527 00:26:53,860 --> 00:26:55,269 bad for us. 528 00:26:55,269 --> 00:26:59,971 Also, Emily, yesterday, talked a lot about writing good 529 00:26:59,980 --> 00:27:02,570 APIs for other developers to be able to make 530 00:27:02,580 --> 00:27:07,539 use of your gems. Again, metaprogramming requires that everyone 531 00:27:07,540 --> 00:27:10,061 else enter your mind of god in order to 532 00:27:10,061 --> 00:27:15,139 code around the barriers that you built. So I 533 00:27:15,140 --> 00:27:19,231 really, really discourage any pattern which looks anything like 534 00:27:19,240 --> 00:27:21,340 taking on the mind of god, taking on the 535 00:27:21,340 --> 00:27:26,080 full level of responsibility for managing all levels of 536 00:27:26,080 --> 00:27:27,889 interaction. 537 00:27:27,889 --> 00:27:33,965 Again, these three particular recipes, and the metaprogramming cannon, 538 00:27:34,000 --> 00:27:39,211 are extremely dangerous. Greppable? Eh, I don't know. Sometimes. 539 00:27:39,220 --> 00:27:42,049 In, depending on how things are made. Are they 540 00:27:42,049 --> 00:27:47,441 graspable? Not really. They usually have very unpredictable behavior. 541 00:27:47,441 --> 00:27:49,840 What I prefer instead are these two bread and 542 00:27:49,860 --> 00:27:54,500 butter solutions out of the object-orientation playbook. Strategies and 543 00:27:54,500 --> 00:27:57,470 delegates. I showed strategies a little bit earlier, where 544 00:27:57,470 --> 00:28:00,409 what would happen is that you say, OK, well 545 00:28:00,409 --> 00:28:02,900 including class, I want you to take on some 546 00:28:02,900 --> 00:28:06,250 behavior, but managing that bolt onto the behavior can 547 00:28:06,250 --> 00:28:07,990 be handled somewhere else. 548 00:28:08,000 --> 00:28:09,361 And this is a type of a interaction that 549 00:28:09,361 --> 00:28:11,610 should be intimately familiar to all of us. As 550 00:28:11,610 --> 00:28:13,859 Americans, well, those of us who are Americans, we 551 00:28:13,860 --> 00:28:17,561 are bred on the model of the assembly line. 552 00:28:17,561 --> 00:28:19,690 The Henry Ford model. The great innovation of Ford 553 00:28:19,720 --> 00:28:22,519 was not the car but the assembly line. 554 00:28:22,520 --> 00:28:25,131 We think about the chassy coming down that assembly 555 00:28:25,131 --> 00:28:28,029 line, it stops at a little station. That station 556 00:28:28,029 --> 00:28:31,011 puts on wheels. The next station puts on windows. 557 00:28:31,020 --> 00:28:33,261 The next station puts on doors. Hopefully it puts 558 00:28:33,261 --> 00:28:35,279 on the doors before the windows, but, yeah. Depending 559 00:28:35,280 --> 00:28:38,951 on which car you have, I suppose. 560 00:28:38,951 --> 00:28:40,889 But the point being is that the idea that 561 00:28:40,889 --> 00:28:43,341 you need to have the chassy go hey, I 562 00:28:43,360 --> 00:28:46,059 need wheels and bolts it on itself. Hey, I 563 00:28:46,060 --> 00:28:48,991 need windows, hey I need doors. You're making that 564 00:28:48,991 --> 00:28:53,120 chassy participate in the mind of god type behavior. 565 00:28:53,120 --> 00:28:55,840 You should think of the classes as you construct 566 00:28:55,840 --> 00:28:58,990 them as being on an assembly line, delegate that 567 00:28:58,990 --> 00:29:02,450 big piece you're building to a station. Ask for 568 00:29:02,450 --> 00:29:05,560 it back. Move down to the next station. Ask 569 00:29:05,560 --> 00:29:09,590 it back. 570 00:29:09,600 --> 00:29:14,420 One other anti-pattern is laziness lookups. Oh, excuse me, 571 00:29:14,420 --> 00:29:15,200 whoops. 572 00:29:15,220 --> 00:29:19,409 Constant_get and constantize. These make your code virtually ungreppable, 573 00:29:19,409 --> 00:29:21,911 as it's very hard to find that place where 574 00:29:21,920 --> 00:29:27,700 somebody chose to, why did they constantize some string 575 00:29:27,700 --> 00:29:30,590 that came from the user? Who knows. It's ungreppable. 576 00:29:30,600 --> 00:29:33,930 Don't do it. I like to type it out, 577 00:29:33,940 --> 00:29:35,090 and I'll just ask the simple question - what's 578 00:29:35,090 --> 00:29:37,190 wrong with a hash? I mean, a hash is 579 00:29:37,200 --> 00:29:39,970 so greppable, a hash is so friendly. You look 580 00:29:39,970 --> 00:29:42,509 at it, you know what's going on. Why do 581 00:29:42,509 --> 00:29:46,010 you need to use constantize? Just, to be cool? 582 00:29:46,010 --> 00:29:48,650 Don't. Don't do that. Don't do it. 583 00:29:48,660 --> 00:29:50,270 So I'd like to talk about principle techniques for 584 00:29:50,270 --> 00:29:54,620 happier programmer. Make lots of small, greppable classes. Lots 585 00:29:54,620 --> 00:29:57,000 of them. There's nothing wrong with lots of classes. 586 00:29:57,000 --> 00:29:58,610 A lot of people say, well, it requires me 587 00:29:58,620 --> 00:30:00,581 to open up a lot of files. If that's 588 00:30:00,581 --> 00:30:03,450 the problem, learn your editor better. Because editors are 589 00:30:03,460 --> 00:30:06,399 now very good at cutting vertically as well as 590 00:30:06,400 --> 00:30:07,140 horizontally. 591 00:30:07,140 --> 00:30:10,880 Things like C-tags, I know, Sublime, FuzzySearch. Be more 592 00:30:10,880 --> 00:30:15,790 comfortable creating lots and lots of tiny classes. Prefer 593 00:30:15,790 --> 00:30:19,691 composition and delegation. That is to say, don't look 594 00:30:19,700 --> 00:30:23,549 to have a mind of god object that rigs 595 00:30:23,549 --> 00:30:28,441 itself together. Look for collaborators within your object space 596 00:30:28,441 --> 00:30:32,340 to provide small, little objects, which are experts in 597 00:30:32,340 --> 00:30:36,420 singular particular fields. 598 00:30:36,420 --> 00:30:38,840 The pattern, or the, the fancy name for this 599 00:30:38,840 --> 00:30:43,029 is, is injection. That's when you create a something 600 00:30:43,029 --> 00:30:47,020 special and then pass it in to an obect 601 00:30:47,020 --> 00:30:51,640 that will create a, a concert of those passed-in 602 00:30:51,640 --> 00:30:53,331 objects. 603 00:30:53,340 --> 00:30:56,830 I encourage you to love dep- inversion. Inversion is 604 00:30:56,840 --> 00:31:01,430 just, it opens up so many pathways of thought, 605 00:31:01,430 --> 00:31:03,019 is that if you think that you need to 606 00:31:03,040 --> 00:31:06,461 manually bolt everything on yourself, participate in that god 607 00:31:06,461 --> 00:31:10,120 pattern, inversion is, is freedom from that. When you 608 00:31:10,120 --> 00:31:13,039 engage in the god pattern delusion, what you are 609 00:31:13,040 --> 00:31:16,150 basically saying is that I don't trust anyone. You're 610 00:31:16,150 --> 00:31:20,380 being a totalitarian. Build small objects. Yield to those 611 00:31:20,380 --> 00:31:22,491 objects. And trust those tiny objects to do the 612 00:31:22,500 --> 00:31:23,669 right thing. 613 00:31:23,669 --> 00:31:27,621 Lastly, a, a thing that's kind of been in 614 00:31:27,621 --> 00:31:29,879 the, in the medics of this conference is well, 615 00:31:29,880 --> 00:31:31,831 what to do about comments. Should we have comments 616 00:31:31,840 --> 00:31:35,200 or not comments? If you embrace the strategy patterns, 617 00:31:35,200 --> 00:31:39,350 your strategies will usually reflect that thing you're commenting. 618 00:31:39,350 --> 00:31:43,820 Like, deal_with_bobs_brain_dead_hack_for_dead locks. If you name a strategy that 619 00:31:43,820 --> 00:31:46,120 way, it's very obvious why you did it, what 620 00:31:46,120 --> 00:31:48,720 it's for, and it turns out that the object 621 00:31:48,720 --> 00:31:51,740 name space can teach other readers of your code 622 00:31:51,740 --> 00:31:54,509 as much about your code as a comment could. 623 00:31:54,509 --> 00:31:57,951 Further, comments age rapidly. Code is always gonna be 624 00:31:57,960 --> 00:32:00,769 executed. So keep in mind that your code will 625 00:32:00,769 --> 00:32:04,120 always speak louder than your comment. 626 00:32:04,120 --> 00:32:09,701 For further reference, practical object-oriented design with Ruby. I 627 00:32:09,701 --> 00:32:11,670 can't sing it highly enough. I was, as a 628 00:32:11,680 --> 00:32:14,320 programmer, I was very frustrated. I was very painted 629 00:32:14,320 --> 00:32:17,480 into a corner. In seven chapters, Sandy Mets can 630 00:32:17,480 --> 00:32:20,269 help you out of your particular corner and will 631 00:32:20,269 --> 00:32:24,931 invite you beyond. By beyond, the next book that 632 00:32:24,940 --> 00:32:27,490 helped me get further out was refactoring the Ruby 633 00:32:27,490 --> 00:32:30,980 edition. And thirdly, the design patterns in Ruby book. 634 00:32:31,000 --> 00:32:32,299 I don't know if they intended it, but Adam 635 00:32:32,300 --> 00:32:34,540 and Wesley have basically built a stack of free 636 00:32:34,540 --> 00:32:37,400 books that are superb at moving you from a 637 00:32:37,400 --> 00:32:42,010 beginner to intermediate Rubyist to maybe an intermediate advanced 638 00:32:42,010 --> 00:32:47,280 object-oriented, object-loving Rubyist. 639 00:32:47,280 --> 00:32:50,851 So winding up, metaprogramming. Don't write more of it. 640 00:32:50,860 --> 00:32:54,600 But let's just stop. Do understand it. The reason 641 00:32:54,600 --> 00:32:55,740 you have to understand it, is well there's a 642 00:32:55,740 --> 00:32:58,549 whole lot of legacy code out there that needs 643 00:32:58,549 --> 00:33:01,991 some refactoring. And the other part is that it's 644 00:33:02,000 --> 00:33:04,230 also a very helpful technique when you're in a 645 00:33:04,230 --> 00:33:07,480 really, really difficult debugger situation. If you need to 646 00:33:07,480 --> 00:33:11,039 live update something it's very handy. Although, that said, 647 00:33:11,040 --> 00:33:13,260 I saw some things in Pry yesterday that make 648 00:33:13,260 --> 00:33:17,211 this less and less of a necessity, so. 649 00:33:17,220 --> 00:33:18,720 Use it only to refactor. It seems to be 650 00:33:18,720 --> 00:33:19,970 the future direction. 651 00:33:19,970 --> 00:33:22,979 I'd like to thank everyone I work with at 652 00:33:22,980 --> 00:33:25,331 Shop it To Me. All of them have dealt 653 00:33:25,360 --> 00:33:28,620 with my kooky ideas about metaprogramming for a long 654 00:33:28,620 --> 00:33:30,950 time, and some of them have let me know 655 00:33:30,950 --> 00:33:34,220 quite noisily that they don't like it. I want 656 00:33:34,220 --> 00:33:35,990 to thank the Addison Wesley authors who have really 657 00:33:36,000 --> 00:33:39,240 tren, a great transitional series for developers. I thank 658 00:33:39,240 --> 00:33:41,640 my lovely girlfriend Lauren who put up with me 659 00:33:41,640 --> 00:33:44,160 yelling about this sort of stuff at dinner. And 660 00:33:44,160 --> 00:33:46,170 I want to thank everyone here because you are 661 00:33:46,170 --> 00:33:50,471 all my favorite garbage collectors. 662 00:33:50,480 --> 00:33:52,749 There is no shame in garbage collecting. It is, 663 00:33:52,749 --> 00:33:56,081 it is a great and noble profession. You have 664 00:33:56,081 --> 00:33:57,980 to keep in mind that the scarab was holy 665 00:33:57,980 --> 00:34:00,159 in Egypt so, and that's the lowliest of the 666 00:34:00,160 --> 00:34:03,231 garbage collectors of all. So I hope that you'll 667 00:34:03,240 --> 00:34:05,610 take forward a lot of the object-oriented techniques that 668 00:34:05,620 --> 00:34:07,830 I've presented to you. I hope that you'll use 669 00:34:07,830 --> 00:34:10,659 them to attack code and furthermore, hope that you'll 670 00:34:10,659 --> 00:34:14,340 forgive me for spreading a bad meme that metaprogramming 671 00:34:14,340 --> 00:34:16,310 was an awesome thing to do. 672 00:34:16,320 --> 00:34:19,731 Thanks so much, and I'll say one last word 673 00:34:19,731 --> 00:34:23,389 is that I hope all of you always have 674 00:34:23,389 --> 00:34:25,080 the courage to face your problems, and when they 675 00:34:25,080 --> 00:34:27,659 feel a little bit too large, just remark to 676 00:34:27,659 --> 00:34:30,741 your heart, all is well. And be ready to 677 00:34:30,741 --> 00:34:32,940 give those talks. I'm ready to hear some new 678 00:34:32,940 --> 00:34:35,018 garbage collectors next year. So thank you again.