 I think I'm actually really excited for this talk. This is, is it bokeh? Actually, technically, it's bokeh, but everyone pronounces it bokeh. Jal's bokeh on cogeneration safety scissors of metaprogramming. Hello. Let's just give it a sec. OK, so I'm actually giving this talk next week in Scotland. And I gave it yesterday in, or the day before, in Philadelphia. So it's evolving. It's an agile talk. Initially, I was going to do it as live coding, just live coding, where it would consist only of code. And I did this. And it kind of went over well, except for a horrible explosion with the microphone, which I don't think is going to be a problem here. And also, well, there's also the issue that I'm losing weight, my pants don't fit anymore. So I was doing the whole thing like this, like that. And the third issue was that I got through the whole thing with a half hour to spare, and just had to kind of wing it after that. So now, it's going to be a combination of live coding and slides. So let's see if I can find those slides. OK, so this being a Ruby conference, the Ruby community is very much into weird languages, not just Ruby. We're known for doing things like Haskell, Erlang, Scala, IO, Factor, all this stuff. So that's kind of intimidating. So what I did is I drew on the weirdest knowledge I know, which is ancient Greek. This is pretty much a personal hero. This is Archimedes. Archimedes was the guy who, you know the word eureka. That comes from him. He was thinking about a problem he was working on. He was like the first famous engineer. He was thinking about a problem he was working on. He was like eureka, which means I got it. And he ran out of the bath all the way home and wrote down the solution. And of course, he was running through the streets of his hometown, Stark Naked. And it was like one of the biggest cities in ancient Greece. He also calculated the value of pi to a very precise approximation using only circles. And when he died, his last words were, do not disturb my circles. Because in ancient Greece, everyone did math with circles. They didn't even use numbers very much. It was all about circles, squares, geometry. And the Romans invaded his hometown when they were building the Roman Empire. He said, do not disturb my circles. And they killed him. But they were actually under orders not to kill him, but they kind of screwed that up. But you can kind of get an idea of how hardcore and cool Archimedes was. Because picture, you're at home, you're coding, a SWAT team busts in, and you say, wait, I'm not finished writing this code. That's how he died. He's also very famous for inventing the lever, which is a very fundamental piece of engineering. And he said, this is the quote, which is horribly mispronounced. But what it means is, give me a place where I could stand and I can move the whole world. Now, although this is a famous engineer, like the prototypical genius engineer, generally speaking, the programming community is not that concerned with ancient Greek. Now, we do all know what pi stands for. We recognize there's a pi right there. Can I? Yeah, this pi. You all know that it stands for a number. But it is kind of obscure, even for a community interested in obscure languages. Mega obscure. However, this is another letter that is well-known to programmers. This is lambda. And if you've worked with prox in Ruby, if you use the lambda keyword, you know that this is actually a fundamental part of Ruby if you're doing particular types of coding. In the Lisp community, where lambda comes from originally, where we got lambda in Ruby, there's this idea of lambda the ultimate because it's such a core idea that when they're talking about the most basic principles of Lisp, they talk about lambda the ultimate. It is just the ability to return code as data and execute it later on. But in the Ruby community, we're not really that fascinated with lambda, although it is ultimate. It is incredibly powerful. We tend to be more interested in a word, this word, meta. And like a lot of things in ancient Greek, this word cannot really be translated into English. So what we did is we just transliterated it, right? And everybody knows that one of the things that Ruby is famous for is metaprogramming, right? Which is programming, programming itself. But the thing is that's not usually what we really do when we're doing metaprogramming, this magic, right? Because it's not metaprogramming, it's just programming. What we're really doing is meta-o-o. If you assume that the fundamental act of programming is operating on stuff that exists, operating on objects or creating objects, then Ruby metaprogramming is correctly metaprogramming. But that's not the fundamental of programming. The fundamental of programming is writing a program. So the only thing that's really meta about metaprogramming is that it is meta-o-o. So my talk is called Code Generation, the safety scissors of metaprogramming. And the idea of this, of course, is that if you're doing metaprogramming, you're doing magic. You're running with scissors, right? Safety scissors, obviously, if you're gonna run with scissors, you're not gonna get as hurt if the scissors are safety scissors. Okay. So Ruby to Ruby that Ezra and Evan were talking about, this allows you to turn Ruby code back into Ruby code. Here's an example. Lambda do puts hello world end returns a callable proc, a block. If you run to Ruby on that, hold on one sec. Let's just give me a second. Okay. So we're gonna call this variable hello world, right? And hello world is just this, and hello world is just this puts hello world. Can everyone see that? Is that visible? Sort of? Okay, cool. So now we have this object hello world, right? Hello world is a object. True. Or if you wanna be grammatically correct, hello world is an object. True. Okay. That doesn't bother most people, but it drives me nuts. Anyway, hello world to Ruby, kaboom, nothing. Okay. So we do this, require Ruby to Ruby. Cool. Okay. And it returns it. And it gives us proc instead of lambda, but that's just because proc and lambda are the same thing. So that's pretty neat. Let's, oh yeah, yeah, no problem. Yeah, that's better, right? Okay. So, that's what Ruby to Ruby does, and it's pretty cool. We can take it a little bit further if we go into a Rails app, right? Let's see. Okay, this is a Rails app. It's got a, oh actually, crap. Let me first show you the model that we're gonna look at. Widget. Okay, so, let's see if I can make it bigger. Okay, so a widget has one foo. We're gonna kill that part. It's got this method. It's a class method. Doesn't do anything particularly fantastic. So, we're back in here. We do script console. We require Ruby to Ruby. Okay. So then we do Ruby to Ruby.translate widget. Hold on. We were not supposed to get that result. I wonder how that happened. Let's try it again. Maybe it will have resolved itself in the meantime. I think it was because, anyway, that's just embarrassing. Okay, now it doesn't work at all, so we do require Ruby to Ruby. Ruby to Ruby, translate widget. The hell is going on? That's interesting. Victory. And I'll just run that through puts because then we get the, you know, gets translated. Okay, so what we have here is very simple, right? It gives us exactly what we were looking at, right? What the hell? Okay, thank you, thank you. Excellent. Let's see what, there we go. Okay, so the only difference here in the Ruby to Ruby version is it changes the syntax. Class to self becomes def self.window. Okay, so that's pretty cool. Although it took longer than I expected. Okay, so when you do Ruby to Ruby, translate widget, that's what you get. Now, when you come back in and you put has one foo back, let's see. Okay, and you get all this other stuff that was plaguing me before, all right? What you get is all the active record magic, all the methods that are added on, you can just see them right there. Now that's a pretty cool way to introspect on an existing app, but it's really kind of just a party trick, right? And obviously, if you're working with Rails, you put has one on and it picks up new methods, that's like duh, like it's no big surprise. Okay, the deal with Rails plugins is that there are, you know, like Ezra was saying, the magic doesn't really scale well on a community level because what you can end up with is a lot of fundamentals modified. This, there's this silly thing, if it's about to write a program that goes through the numbers from one to 100 and puts out fizz on three, buzz on five, and fizz, buzz on 15, and multiples of three, five, or 15, right? So one way you can do it is by opening up class fixnum and implementing it in 2S on a fixnum, but that's overkill. In fact, it's ridiculous. It's a very bad idea. And this is why people object to monkey patching, right? Because if you have a lot of monkey patching going on, you end up with a very tangled object graph, and that also applies to the graph connecting all the methods, right? Where does this method come in? What file did it come from? When did it change shape to this new shape? So people are saying, stop monkey patching, right? There's this monkey patching is destroying Ruby, which, you know, it's kind of overkill. As a response to that, Pat Maddox, he came up with something which I have to say really is metaprogramming because it's a meta alias method chain. What he did is he said alias method chain to alias method chain with logging, right? So alias method chain itself gets in it, or alias method, gets an alias method run on it to incorporate logging. So then anytime a method is aliased with alias method chain, you get a log of that process. So then when you run your code, it just puts to the standard out, this method was alias method chain to this other method. And that gives you a log, like a log file that you can read and you can say, oh, this is what happened, which is kind of cool. Tests and specs are important, but I can't remember why I put them here. So let me just say I like tests and I hate debuggers. I really just don't think debuggers matter. Now let me get back to my point. That's what you get when there's too many slides. Pat's solution was cool, but it only addresses a small subset of the problems that you can create with excessive monkey patching. So the solution I came up with was to monkey patch monkey patching itself, which of course is meta monkey patching. So the first tool that I need to make this happen is Rubinius, right? The second tool, now obviously everyone's heard what Rubinius is, the second tool is Nodebox. Nodebox is something from the Python community. There's a lot of people, in fact, that thing from Pat, he said, you know, this makes everyone in the Python community my bitch because they're afraid of monkey patching, ha ha ha. I disagree with that. Pat's very, very smart and he's cool, but I disagree with that because this whole attitude of like this other language has to be bad in order for my language to be good is complete and utter bullshit. This is a very powerful tool. What this does is it's basically Photoshop with a Python scripting interface. So that's the second tool to monkey patch monkey patching itself with. The third tool is this idea that code is data and that's basically what we were talking about second ago with Lambda the ultimate. So now I gotta actually demo some code. Let's see what we got here. Whoops. I actually knew that was gonna happen but I just couldn't resist. Okay, here is some relevant code. This is actually very disorienting trying to do this with my head turned sideways. See what I get. Okay, so if you notice at the very top it might be hard to see but the name of this file is dumb.rb and I hope you can figure out from that that this was a sketch. What I was doing is I was thinking about this. I was at this cafe, I was having my breakfast and this part here I was originally running this in Rubinius as the Rubinius equivalent of IRB. Now Rubinius being a pure Ruby implementation of Ruby has code like this, class class, which is insane. I don't know how it works but what it allows you to do, I really have no idea. It makes my head hurt, you know? Anyway, what it allows you to do is you can do an alias method chain on new, right? Class new. So the same trick that Pat came up with for making a log of alias method chaining, I created the similar thing for any time you instantiate a class, creating a new whatever, right? Down here, any time you inherit a method, or no, I'm sorry, any time it inherits from a superclass, it logs inherited from the superclass. Down here, oops, no, it's okay. Sorry. Down here, add method, right? Anytime you incorporate a module, it adds methods to whatever you incorporated, whatever incorporated the module and it uses this internal class, this internal method, sorry, add method, right? With the underscores, this is like in Python. The double underscores indicate that it's secret, right? So what it does is if you add a method to an object, it says I'm in yourself adding your name, right? Which is to say I'm in your object adding your method. Okay. And there might have been some other stuff in here, but what I did is I ran this against some code, right? And it produced results, right? And let's see, let's see what I get here. Okay, oh, that's the wrong one, damn. Okay, I'm in your oatmeal, adding your cranberries. That's kind of eccentric, but let me explain that one. Down here, I created this thing, module oatmeal has a method called cranberries, include oatmeal, et cetera, right? Creating a new included module, creating a new method table, breakfast cafe, inherits from string, creating a new breakfast cafe, and when you call the method, it just returns cranberries. By the way, if you are, well, this is a tangent, but this morning I had oatmeal with raspberries, which is very smart. So I took this, and this is kind of silly and trivial and not particularly useful, and I changed it into something which was kind of useful. And that's not it. This is it. What it does here is I just took those, I'm in your x, adding your y, I'm creating a new whatever. I took that and I just changed it to return Ruby code, right? So now instead of printing random text to the screen, like a log file, what it's doing is it's creating code. Now there's no reason that you couldn't put executable code in a log file, and I'm planning to do this for reasons which are very complicated and I will not explain now, but you could do it, and what I did is I did it right here. When you run this code, let's go back to the terminal. If you run this code, shotgun Rubinius node boxer. Instead of getting the stuff that you can read, you get the stuff that a computer can read, right? Extensions, extension new oatmeal cranberries, indicating that you extended, actually that's a bad example, but instantiation makes perfect sense, right? Instantiation is an instantiation new, you just add them to these instance variables, right? So then you might wonder why on earth I would do that. The reason is it produces this output, which is code, right? This fundamental idea that code is data, you create some data which is code, and this thing here, I just had it go through these, create these objects so that creating a new one was meaningful, right? And then go through these collections, eval the file that had a list of all the instantiations, extensions, and so on and so forth, and have it do puts and just say what was created, right? So that is eval, so I'll just show you that one. And just so you know, there is a point and it does get interesting at the end. Okay, what it does is it creates these objects and you can see that these objects were created. But again, you're just putting it to standard out, right? That's, you know, what are you gonna do with that? So then I created another version which altered only one line, right? And what it does is it goes erb and it pipes these variables into an erb template for a graph in Python. And that's the erb template. And as you can see, all the coordinates, right, this stuff here is hard-coded, right? I didn't create a particle system because it was outside of the scope of the discussion. However, those things are actually quite easy to create. Let me see if I can show you, depending on the network, I may or may not be able to. Yeah, cool. So hopefully you can see that this is a bunch of lines moving around. And what it is is actually it's a simple particle system in Flash. It took me an afternoon. It's very easy to do. So we go back here and we've got this templator, right? So I'll spare you the details, but when you run it, you end up with Python that populates a graph drawing program for NodeBoxer, or for NodeBox with these things that you have created. So basically what you're doing is you're using logging against the code that exists. You're having, you monkey patch Rubinius to generate code which generates a graph. And let me see if I can find it. Yes. And this is what that graph looks like. And obviously it is not stunning, right? It is not gorgeous. It is a simple object graph created in NodeBox, okay? This tangled object graph was also created in NodeBox. This is a fractal project by somebody who wanted to see what kind of art they could create with NodeBox. Now the thing is, right, you've got the same tool, but they generate different output, right? What I just showed you is a proof of concept, right? There's no reason that you couldn't create something this complicated and just have it populate it with whatever variables happen to be in the Ruby code, right? So now here I am criticizing debuggers, right? And debuggers suck, that's my opinion. But basically I just built one, right? Here now in the space of like five, 10 minutes, okay? So some people want debuggers, right? They time out for a picture of Darth Vader wearing a sombrero. Okay, time back in. They complain that Ruby has no tool support, right? It does not take long to add tool support to Ruby. It took a day, right? Sitting in a cafe eating oatmeal with cranberries, right? The most idiosyncratic thing about this code is that it mentions oatmeal with cranberries. Everything else is trivial to understand. I don't think anyone here sat there and was like, wow, this is weird, even though you don't see people doing this every day, every step is pretty easy to understand, right? So people are like against monkey patching. I say shock the monkey, just go ahead and do it. So what makes this possible is powerful tools, right? You have Rubinius, which is an amazingly powerful, even though it's not finished yet, is amazingly powerful and amazingly useful. You got Nodebox, which is also very powerful, also very useful. And last, as I said, you have code equals data, right? And what I wanna suggest is that this might be, you know, at least as powerful as the other tools, possibly more so. This idea that code equals data. So I first discovered this when I was working at E-Trade and I was building a CMS and it generated HTML, right? And it created hundreds and hundreds of, not even SVN. We didn't have SVN at the time. CVS and RCS commits, 700, I think, round number. It would just create these as a web app. Hundreds and hundreds of lines of Unix. Every time you used it for anything. And I didn't really realize how powerful that stuff was at the time. But this book, which I meant to bring with me and didn't, this book is a really good book and you should read this book. And I've only ever heard one other person or read one other person say that. The other person who said that is David Hanema Hansen who created Rails. This book came out in 2003 and pretty much every idea in this book is in Rails. Now, the way this book starts is it starts with an EJB application, right? It was 2003. You've got a legacy app with 150 tables. You're using EJB, so you need seven files for every table that you wanna grok with your app. So that comes out, seven times 150, that comes out to 1,050 Java files, right? By hand, that takes a very long time to create. With generators, he created it very, very swiftly, right? And at the time, a lot of people were wrestling with EJB apps, right? To be able to say, this project, which is gonna take you guys three years or more if you bring me on as a consultant, I'll get it done in two months. That's a very powerful, competitive edge. Here's Darth Vader again. The thing is, okay, last night, I got in and Joe O'Brien and Jim Wyrick were in the lobby and Pat, who organized this conference, Pat Eiler, but Pat didn't accompany us for this part. We went and we had some beers, and at the end of our conversation, decided that I needed to have pictures of Darth Vader wearing a sombrero, and I don't remember why. So anyway, this book, it goes over things like generator types, generating UIs, unit tests, embedding SQL with generators, creating database access, all this stuff, right? And if these things sound familiar, it's because, as I said, every single one of these ideas ended up in Rails, right? In Rails, you've got script-generate, scaffold, resource, plugin, migration, script-generate itself, you've got the Rails command, which is a code generator. Axe is authenticated and it's SQL, RESTful authentication, all these things, including what was initially Rails' biggest selling point to serious programmers, all these things are code generators. Rails makes code generation a core strategy, and everybody who talks about Rails is there like, magic makes programmers more productive, bullshit. Code generation makes programmers more productive, especially if it's really well done, which in this case it is. Here's another gratuitous picture. This is Jessica Alba. So anyway, my point is code generation for the win, right? When you've got code equals data, that's a really good thing. But since this comes from Lisp, this fundamental idea, let's put it in Lisp terms, right? This is how it would look in Lisp. And the problem with putting it in Lisp terms is it suddenly becomes something nobody in the room can understand. I think in the Lisp community, they consider that to be a feature. I really do. Anyway, another book that was kind of crucial in helping me understand this idea, right? Where you can get a lot done without particularly complicated code, is this book on Lisp, which is by Paul Graham, right? And everybody knows that Paul Graham made a ton of money with Lisp and has been blogging about it ever since. This book was written before that period began. And it's all technical, it's a really good book. The fundamental idea is functions which return functions which returns functions, et cetera, et cetera. Higher order programming, where you write code that writes code for you, right? Essentially what you're doing is leveraging the lambda calculus, lambda the ultimate, to create code which generates data which runs as code, dah, dah, dah, dah, dah. Okay, one way that this has been used in the Lisp community, there was a guy who had to create a app that would generate forms based on extremely convoluted logic which had to be different for every user, for almost every day, for almost everything that they could be addressing with the app. They were doing pharmaceutical evaluations, okay? The balance of power in a pharmaceutical evaluation is with the user, the user is a doctor. The pharmaceutical companies beg them to evaluate their drugs. And the system has to be efficient because the only way to get financial value from creating a drug is to own the patent. And you cannot begin the evaluation process until you have the patent. And the evaluation process can take years and the patent only lasts for five years. So it's very important for them to leverage that very quickly but because the balance of power is with the doctors, it's completely up to them whether they fill out the form correctly or not and most of them choose not. So they had to have this extremely flexible thing which they could also change every week because the conditions of what they wanted to track in the evaluation wanted to change every week. So picture a Rails app which is only about submitting forms but the form can be a different form for every user. The users don't have to fill out anything they don't want to and you have to be able to change the logic which generates these forms on a per user basis with no validation. You have to be able to change that logic every week, okay? This would be really hard with Rails. I think you could do it with Seaside. The way they solved this is one guy, a list coder, single-handedly did it in about a month and the way he did it is you store the code which generates the form in the database and when you need it, you pull it back out. And by the way, he also had to be able to render it to multiple types of presentation, right? In addition to being able to generate these Rails things, he had to, you know, these forms, he also had to be able to generate the equivalent of PDFs at the time, stuff you could print out, right? And he did it in a month because he was able to simply store all the code in the database, pull it out and execute it. So although metaprogramming is cool, Lisp macros win. They really do. They give you a lot more power. And by the way, you can do them in Perl. Perl is another language like Python which sometimes gets bashed by maybe overzealous Ruby partisans. I love Perl. I think it's a fantastic language. Not necessarily pretty, but fantastic. It gives you incredible power. But a lot of the stuff that you can do in Perl, with higher order Perl, you can do in Ruby and it'll be more compact and cleaner. There's only one thing of this type of programming that I think is cleaner in Perl and it's kind of an edge case. Well, no, it's not. It appears to be an edge case for Rubyists. It is standard in Perl. It's really kick ass. Anyway, yes, Perl, Jessica, Alba, Monkeys. Anyway, Lambda the ultimate, right? This is a big thing in the Lisp community. One thing that Lispers are obsessed with is this idea of Lambda the ultimate. Another thing they're obsessed with is why the combinator, right? And that's because it has two meanings, okay? Why combinator is a particular type of strategy for generating code from the Lisp community which is of a similar level of power as Lambda, except it's really made out of Lambda, but it's still extremely powerful, okay? The other reason that why combinator is prominent in the Lisp community is because that's Paul Graham's startup incubator and he's really the only huge success story that the Lisp community has had in a long time, right? And you can figure out that there must be something wrong with Lisp because it's the, or perhaps the software industry, because it's this amazingly powerful language and it's number one use case is pimping out text editors, right? I mean picture if you went to the doctor, right? And they're like, I've got this laser scalpel, you know? I use it to open my envelopes. Now it's time to operate on you. Let me get my sharpened rocks, okay? That's what we have with Lisp in text editors and all these, you know, C++. You know, why would anyone use that? I don't know, anyway. So why combinator is associated with programming power and it's also associated with money, right? Paul Graham talks a lot about how you can make a ton of money with a very small company if you're doing a startup, right? So that's kind of one of his main things, small teams. Another one of his big things is this idea of code generation or I guess that would be more accurately of Lambda, right? Code which generates code. So the thing is if you take this idea that small teams are better because they're faster, right? Which is basically that's a whole ton of Paul Graham, you know, narrowed down. If you take that idea and you combine it with this idea that writing programs which generate programs, writing code which generates code is a very powerful strategy. This is my one sentence summary of Paul Graham, right? Great programmers can write better programmers than they can hire. The thing is that's better programming. There's just one word in that that I don't agree with and the word is great, right? Paul Graham went to Harvard and I have some friends who went to Harvard and some who even went to grad school there and they also overemphasize things that they agree with being great. It's kind of a cultural flaw with Harvard. Harvard thinks that other things in the world cannot possibly be as good, okay? And this is kind of connected to the Lisp community, right? This is how Lisp guys think of Lisp and the Lisp community, right? I don't know how well this shows up. Can you guys see this? Here's my summary, right? It's intergalactic, voluntarily bald, cloned wizards of time and space who the women's are belusting for, right? The wizards, they're bald, you know, they want to be bald, there's time and space, ooh, they're special. The thing is, this is the Lisp community self-image in my opinion, right? If you take this self-image, right? And you say that the Lisp community had a project which is to communicate their self-image to the world outside, right? Which in a sort of deep sense is the project that anyone has who talks to another human being, right? If you were to evaluate on that project, you would either give them a grade of fail, right? Or a grade of epic fail, right? Is the thing is most people do not think of Lisp, ooh, they think, oh, power, no, they think parentheses, code that nobody can read, right? So while the Lisp guys are going on about incredible power, right? They have no emphasis at all on simple clarity and that is why nobody uses Lisp, right? And it comes back to that thing, this is the next slide I added during Ezra's talk of simplicity over magic, right? I forgot what I was gonna say next. Oh yeah, so here's this thing, right? You've got these languages like Pearl and Lisp which have incredible power but nothing in the way of simplicity. It's very difficult to read these things, right? These languages, their power is never fully exploited. Now, Ruby has pretty much the same level of power and if you're working with Rubinius, I think it's equal. In that case, you've got on the one hand, incredible power wrapped up in parentheses that no one else can read. That makes you a wizard, right? But if you take that same incredible power and you put it in terms that anybody can use it, right? You're not making yourself a wizard. You're making everybody who looks at your code, reads your code, uses your code, everybody becomes more effective, right? Instead of hoarding this magical treasure and wrapping it in layers of mystery so that only you can use it, you're making it a public resource and that's what Ruby does. So instead of saying great programmers can write better programmers than they can hire, I would prefer to say skilled programmers can write better programmers than they can hire and the skill is in this book which is why you should read this book. This book is a total sleeper. No one has read it. I don't understand. It's madness. Everyone should read this book and that's kind of my main point, actually. It's a really good book. So you've got this stuff, right? Code which generates data which runs as code, dah, dah, dah, dah. Now as I said, I first discovered this with like a Pearl CMS, right? It doesn't have to be Ruby. You can do this with anything. Although it seems to be having the most success with Ruby and Code Generation in Action was one of the first Ruby books in English. He actually pitched it as a Ruby book but was unable to get the publisher interested so what he did is he said let me write a book on the general topic of Code Generation across several languages and I'll use Ruby as the language for Code Generating and it is very well specced for that use case but because on a Unix system it's very trivial to write code which generates data which runs as code, it's possible that you could say Unix is a Lisp. It's possible that you could say many of the boxes in this room have that same level of power, right? The only real question is whether or not Lisp parentheses and syntax are required for something to be a Lisp. I would say no. So I would say this same power is sitting on your machines right now. This whole thing of like let's create an object graph generator before lunch. It's doable, right? And it's not that difficult. So the last thing and I've got 10 minutes for questions so this is on the dot unless, well it's on the dot if you guys have good questions or if I can freestyle. But this here, this Greek, right? Give me a place to stand and the whole world I can move, right? My suggestion is that Ruby is that place to stand, right? You can take this stuff and you can leverage it and you can produce all kinds of interesting results and because I got a couple more minutes, let me tell you one example, right? I'm working on a system which auto generates music, okay? Now I have a friend who did this. He was a DJ, a techno DJ in San Francisco and he got into doing this, coming up with his experiments and the thing he told me, the number one thing you need to do, especially if your code uses random numbers is record everything because sooner or later your random number generator combined with your code is gonna create music that is awesome and you will never hear it again and the same code can generate music which is crap. So you can be like, damn, that was awesome. You play it again, it's gone forever, right? So what I need to be able to do is I need to be able to record all the music that this thing creates. Now I'm planning to use this for live performance at raves and nightclubs, okay? A live performance at a rave and nightclub, it's not like creating a song the last six minutes. What you're doing is you're creating a stream of music that goes for an hour, two hours. There are DJs who do 12 hour sets. Now you would need a big fucking hard drive to record a 12 hour set and there are people like Ezra who are really fucking wicked with performance profiling infrastructure. My brain turns off with that. I mean, when he was talking about it before, I was like, oh my God, this is amazing because seeing it in action, I can say, damn, that's good. But actually doing it, it's just, I can't do it, it's boring to me, right? So for me to hook up a system that records physical music onto a physical hard drive for 12 hours or at least one, somewhere between one hour and 12 hours at high fidelity, that would be a nightmare. So what I'm gonna do is this system, when it generates music, it's also going to generate a log, which is code, which will be instructions to itself for generating that music again. And certain parts of this system will use a lot of loops and samples. It'll include the names of the loops and samples and by doing that, I'll be able to index it in a trivial manner. I'll be able to locate bits I remember using grep and then I'll be able to feed those bits back into the system and it'll create the music for me on the fly. So, long story short, I really think everyone in this room, everyone in the world who writes code should read that book. Thank you. Any questions? Okay. Hi. If you're already a, do you think that guy or that, that guy? Oh, that guy, I don't think that guy. If you're already going into the vowels of the word inus, and to put it closer, recording things and logging stuff, why not go all the way and just expand the amount of metadata that is contained in the program structure of the word inus, so that you can navigate this stuff to be in situ rather than putting it in the log, would you have to go over the history of things? By navigate it in situ, do you mean like build the grapher into the language? Yeah, sure. If you have a method that is ableist, you can just set it back where you're doing it. Yeah, that's a great idea. That's, yeah, hopefully more than one of that guy. You know what I mean? That's a great idea. I mean, that's what Archive does essentially, right? It builds the logging facility into the binary, right? All your, you could make the graphics, you know. It's a linear accomplish stuff. I'm saying if you're, if you're extending it, Ruby already has a bunch of metadata that it says it's top class, it knows what it's super class, et cetera. All this stuff that you're trying to do is saying, you know, when I do my database method chain for a traffic of where the chain is happening, you could extend the language to know about that concept. So instead of it having to be an ad hoc addition to the language, you have to be supported by the language so that you can not fix and see what your chains are. Yeah, and I think in the future, that will actually be a major use case for Rubinius because a lot of the dynamic stuff that you can do inside, you know, Eclipse with an AST, right? Like, I don't like Eclipse. When I was writing Java, I would use Eclipse as a searcher and I would use it to navigate the AST but I would do everything else in VI. I mean, it was literally just a window that I would use for the searching and the analysis but being able to click on something and immediately find out what this object is, where it is in its life cycle, where it was defined, what it picked up from other methods or modules or what have you, that stuff is something that makes Eclipse very powerful for certain use cases and it's something you can't do in Ruby right now but with Rubinius, you'll be able to do that. And so I think that's actually, I don't know if that's part of the goal but I think people are already working on that. I can't say any specifics but I've heard rumors that this may, in fact, be happening. So yeah, I think not only is that a really good idea but I think other people are working on variations of the idea and will be good. I don't understand why Rubinius is needed at all for that. Class new? You can define class new. Really? Yeah. Let's see what happens. I don't think you know where I've been to. What's that? You can't hook into where the method gets from the method that you're working on. Oh, I see what you're saying. But you can call it, you can alias the old, the former new to be old new, new to be old new. Right, so we've got top part of this thing that will work but the bottom part where you hooked into the creation method is not what's left of it. I guess that's all. I think that you like redoing that, I think so that it was in the method there. There's a hook into Morai for method edit. Sorry, I'm only paying attention. I just tried to do it, right? And it blew up. What I did, I'll go back in because unfortunately I was using VI from within IRB which is my clever trick or whatever. So class class, right? Def new, maybe just the implementation was wrong but when I string.new, it must have worked but it blew up. Yeah, yeah, okay, stack a little 2D. What's happening is that you're making a string so it's calling new class. Oh, yeah, good point, very good point. Okay, hold on. So we'll put that on, let's see, I don't know. I still think you've just got all that I guess, I don't know. So we'll have it return four or I guess three. That's still gonna make it blow up then. It's what? It's still gonna blow up? It might blow up. Well, I mean it could be correct. Three days. Okay, so string new. Yeah, so I'm not sure exactly. It's for the long story short so it blows up and it blows up instead. It's doable, it's just dangerous as you see. Yeah, so it's still creating new data. Well, the first thing is dangerous. So I'll just, it's very hard to avoid creating new obliques and things like that. Right, right, right. So I don't know if that answers the question. So for, I guess class creation is a little bit different. If you're trying to catch new for certain classes you could do that to redefine like the instance method new on class, yeah that would probably screw up in line, but if you were to say look up like active record basing it or something. Right, it isn't fundamentally different from what Ruby gives you. It's just that there's this one level left in MRI that you can get to. I mean the classic example is array brackets, right? You can redefine the brackets and then iterate, but if you do, they won't do anything because the thing that happens is that you point in C. So what it does as it goes and it gets to the brackets and it says, oh, that's in C now because it's a C and it never even sees the change you made. In rebellions you can do things like this. But it's only for that extra, you know, it's named 20 and the 20 in this case is like two. Anyway, there's another question I have. I mean I remember something I forgot to say. But. Practice safe stacks. Zero. Practice safe stacks. Practice safe stacks. Practice safe stacks. Yes, no, this is a good idea. Okay, so someone was asking me before my talk, they were like Giles, I read your blog. I'm really excited to see this talk because I read the proposal or the description because I'm really curious what you're gonna say about how to unit test metaprogramming. Because I said in my description of the talk that I was gonna show you how to do that and then I forgot. So what I'm gonna do is give you like a real brief overview of a way you could do it. You've got some kind of metaprogramming that changes everything, right? And you're like holy crap, how am I gonna unit test this? Okay, so what you do is you have some set of unit tests that work for your project or your language. Rubinius has a fantastic set of specs that is only getting bigger, you know, and your project should be in the same situation. If you run these and it works and then you set up your metaprogramming including something as weird as redefining class new, you should still be able to run those specs without any explosions. So the long and the short of it is that if you want to unit test metaprogramming, all you gotta do is either wait for Rubinius to be finished or help it happen. Because even though there are some flaws to unit testing metaprogramming today, those flaws are gonna disappear. Okay, I think I'm out, think I'm done.