 I'm Godfrey. You can find me on the internet as at Schenken Code. And I work for a consulting agency in Vancouver called Brutals. We basically help people design and build stuff. So if you need help building your next Rails app or JavaScript app, please give us a call. We're a pretty awesome team. And as Luke mentioned, I am from Canada. And I'm a Canadian. From what I hear, we are basically known for free things among the Americans. The Canadian accent, health care, and Texas. I'm so sorry for the title, Wrong Texas. If you want to learn about or practice your Canadian accent, I made a jump for you. Simply jump and start Canada on your computer. And you'll be able to computer like a true Canadian would. So that takes care of the accent. About health care, to be honest, we don't actually talk about that much in Canada. And I really have no idea what health care is all about. So unfortunately, I can't tell you too much about it. But as for Texas, basically everyone hates it. I really do not enjoy doing accounting. And every year, I get really stressed out about it in April. Fortunately for me, I recently bought a Kindle. And I'll source all my bookkeeping to Amazon. So hopefully, things would get better from there. Bookkeeping, Amazon Kindle, bookkeeping, Kindle. OK, I am also a member of the Rails core team. As you learned from Eileen this morning, that means that I get a tweet from the Rails Twitter account. But beyond that, that basically adds zero credibility to what I'm about to tell you. And it's very important for you to remember that for the rest of the talk. What it actually means, though, is being on the Rails core team and means that I get to work alongside some really smart people like DHH, Aaron Patterson, and Eileen. On one hand, that's pretty awesome to be able to learn from these people. But on the other hand, it does make me feel inadequate sometimes. I mean, these are thought leaders and Ruby heroes, right? Like, what am I doing here? So I decided it is time for me to out my game and become a thought leader myself. Fortunately for me, there are a lot of resource out there these days for anyone that's willing to learn. You can probably find this book in your local library. The promise is to transform you from regular dummy to a thought leader. That's a little bit too basic for me, though. And my personal favorite is this other book from a different publisher. Because it's written by some of my favorite thought leaders in the industry. So I ordered a copy of this book on my Kindle. And I was really excited to find out what's in store for me and try it out. This book definitely does not disappoint. I only had time to read the first chapter on my flight here, but I already learned some very valuable lessons that I can apply to my talk today. Here, I learned that one common tactic among thought leaders is to create controversies. For example, David famously pronounced the death of TDD at his Rails confidant last year, which sparked a lot of controversies and made him really famous, even among people that doesn't know what Rails is. So I was really inspired by this, and I decided to make this talk as controversial as possible. And to start, I would like to pronounce death of something. And I would like to announce that thought leadership is now dead. My name is Godfrey, and I'm allowed to think whatever I want. Take that, thought leaders. Seriously, though, all the Rails contributors are really awesome people. And if you're interested in contributing to Rails or just keeping up with the latest changes in Rails in general, I help run this newsletter called This Week in Rails. You can subscribe to it on this website, or you can read it on Rails blog every Friday. You should also come talk to us at the conference. We would love to give you some pointers to help you get started. Anyway, that's enough about Canada and Rails. Let's get to the real talk. All right, let's talk about JavaScript. I know we all love Ruby. That's why we're here. But deep down, we all know it. Unlike JavaScript, Ruby is not web scale. Every once in a while, and you will need to get really close to the metal, and you have no choice but to use JavaScript. Let's talk about what makes JavaScript so fast. That's right. The secret is in the syntax. You see, JavaScript has a very fast syntax. I'll give you an example. JIT hints. Most of the JavaScript run times have a just-in-time compiler to make things really fast. But the JavaScript syntax allows you to drop in some hints for a compiler to make things even faster. For example, let's say you have a triangle. You know the length of side A and B, and you're wondering what this length of side C is. You might remember this from your high school geometry class. You can get the length of the first side by calculating the square root of A squared plus B squared. If that doesn't ring, don't worry about it. The actual purpose of this formula is irrelevant to the example. So let's implement the triangle formula in JavaScript. First, you probably stop by writing a function that computes the square of a number. And from there, you would write another function that actually implement the formula using the square function you implemented. So square root of A squared plus B squared. Pretty straightforward. What you might not know is that you can sprinkle in a few more lines of code, and your code will automatically become faster. Specifically, because JavaScript is a weekly type language, even though this is really obvious to you that the inputs are supposed to be numbers, it is not obvious to the compiler. But don't worry. By adding some unary plus operators here and there, your code will automatically become faster because the compiler now know what you expect from those inputs. And bam, now your code is 5% faster. Not too bad for just a few characters. All right. In case you don't believe me, I made a chart. As you can now clearly see, it is actually much faster. But as with most marketing charts, it did not start from zero. So that seems fine to me personally. But if you insist, it looks like this if you reposition the x-axis with zero. Anyway, as you can see, that's just a quick example. But like I already showed, case y, JavaScript is such a powerful language. So that got me thinking. What if we can combine the JavaScript syntax, which is very fast, with the Ruby virtual machine, which is full of magic. Perhaps maybe we'll just get the best of both worlds, and everything will be awesome. So if you are already sold after this introduction, the code is already published on the internet. You can get it by running German-style JavaScript. If you're impatient, you can just download that now and ignore me for the rest of the talk. But for the rest of you, we'll build this thing together right now. Let's talk about Java for a moment. Let's say, hypothetically, you have a Hello World program written in Java. And it's OK if you don't know Java. This is basically the standard Hello World example copy from the Java website. Now, what do you think would happen if we save this file with a .rb extension and run it with Ruby? Would it just work in print Hello World? Or would it give you a syntax error? Or would it give you a runtime error? Let's fault. Who thinks it's going to be A, some small amount of hints? Who thinks it's going to be B, more hints? And C? OK, a few hints. As it turns out, the correct answer is B. It's a syntax error. But what does that even mean? Well, to understand that, we have to understand how Ruby works. From your perspective, you just write some Ruby code and you throw it at the interpreter and it runs the code for you. But what actually happens on your hood at a very high level is a two-step process. The first step is for the interpreter to try to understand your code at a syntactical level, which we call parsing. And once it understood your code, it can actually evaluate them for you. If at the parsing step, the interpreter thinks that your code is so broken that it doesn't even understand it, they will refuse to continue and throw a syntax error, which is what we got earlier. Obviously, since your code is not even runnable, a syntax error is not something that you can rescue and recover from within the code that cost it. On the other hand, if the interpreter understands the basic meaning and structure of your code, but they found problems with it later on at execution time, it would give you a runtime error. This could be anything from a divide by zero error or no method error. And that's probably something that you're more used to dealing with on a day-to-day basis as a Ruby programmer. Fortunately for us, because our code is now running in the Ruby VM, we can actually anticipate these errors and rescue from them and try to recover from the error states. Enough of our Ruby, let's talk about JavaScript. Hypothetically, let's say you have a hollow out example written in JavaScript. What do you think would happen if you save that as JavaScript.rb and try to run it with Ruby? Would it just work? Would it give you a syntax error? Or would it give you a runtime error? Let's vote. Who thinks it is A? Okay, no one. B? C? Okay, wow, most of you are really smart. The correct answer is C. This is a runtime error. This is a good news because now that we are in the second stage, the Ruby interpreter actually understands how code is syntactic level and so we can possibly recover it from this and try to make it work. To do that, we need to understand how Ruby sees this piece of code. First, it thinks that you're trying to find a local variable or method named console and you're trying to take the result of that variable lookup or method call and call a lock method on it and we know that parentheses are optional in Ruby so we ignore these and finally, we are passing a single argument to the method called lock and in this case, the argument is the string literal hello world. And at the end, we have a semicolon that we know that semicolons are optional in Ruby so we can also ignore it. So looking at the error message again, Ruby is basically complaining that it doesn't know what console refers to. That's easy enough to fix. We can just define a class with an instance method called log and then we can assign an instance of this class to the local variable called console and if we save this, run it again, it would do exactly what we expected and we'll print hello world to the screen and with that, we have successfully executed our first line of JavaScript in the Ruby VM success. If you look at it closely though, there's a problem. We are first of all leaking a top level variable which is not very nice and we're also mixing the Ruby code with the JavaScript code which is like a little bit annoying to read. Ideally, we want to keep all the boilerplate in a file that we require and then maybe keep all the JavaScript code in block for bonus points. In other words, we are trying to write domain-specific language in Ruby. Fortunately, this is a really well-established frontier in the Ruby community. If you remember rake, rspec, or even rouse.rb in your Rails app, these are all examples of Ruby DSLs and the number one weapon for writing Ruby DSLs is using instance exec which lets you take a block and run it in the context of an arbitrary object or in other words, you can change what the self pointer points to when executing the block. This is really handy so we can basically just define a class called contacts. Well, you can call it whatever you want but I call it contacts and whenever you want to run some JavaScript code in stand shape and instance of this object and we'll call instance exec with the block. Because Ruby allows you to omit the self-cured when calling a method on the same object, this essentially allows you to provide arbitrary global methods to the JavaScript block without actually using global methods which is pretty neat, so success. Let's talk about variables. This is how you define a variable in JavaScript. var message equals hello world. What do you think would happen when we try to run this code? Would it just work? Or would it give you a syntax error? Or maybe a no method error or name error? Now before you vote, I would like to point out that no method error and name errors are specific examples of runtime errors and you can basically assume that for the rest of the talk. Like anything that's not a syntax error you can assume that's a runtime error. So who would like to vote for A? No one and any hands for B? Any hands for C? And any hands for D? Okay, the correct answer according to the Ruby interpreter is C, no method error. But if you voted for a name error you're still technically correct because no method error is a class of name error. So just one of them is more specific than the other. But any who, regardless of what the error is it's great news because there's a runtime error and not a syntax error. So that means we can fix this. So to do that let's look at how Ruby looks at a code. Now this doesn't really look like Ruby code to me but how come we're not getting a syntax error? Well, it turns out that if you look at this in the right way this is actually plausible Ruby code. Ruby assume that we're trying to call method called var here which can be make more obvious by inserting those optional parentheses. And let's start from the back. So first we have the optional semicolon and then we have those optional parentheses that we just inserted for clarity and we have a string literal which we then assign to a local variable called message and then we call the method var with whatever happens inside those parentheses. It turns out that variable assignments in Ruby has a value. So the value of an assignment expression in Ruby is basically the value being assigned which is the thing on the right hand side or in this case string literal hello world. So we can basically rewrite this as message equals hello world and then we call var with message. So hopefully that makes more sense now as you can see because Ruby doesn't require any special syntax for declaring a local variable. The first line basically did all we wanted to accomplish. So we don't actually need the var method to do anything. We just need it to not blow up. And if you look at the error message again Ruby is complaining that we have not defined a method called var. So that's pretty easy to fix. We can just define a method called var that does nothing and if we run the code again, it will work and more success. Let's talk about an initialize variables. In JavaScript it is possible to declare a variable without actually initializing it to anything. As you can see that's like var message on the top and you didn't assign it to any value when you declared a variable. What do you think would happen if we run this code? Do you think it would just work? Or do you think we'll get a syntax error this time? Or maybe a no method error or maybe a name error? Who thinks it is A? Okay, we have a few hands. Who thinks it is B? No hands for B. C, okay, we have some hands. And D, okay, we have roughly the same amount of hands for C and D. The correct answer is a name error this time. Why is that? Well unlike JavaScript, Ruby has no variable hoisting. So since we never defined a local variable called message before the first line, Ruby is assuming that we're trying to call a method called message. Which we can make clear by inserting those optional parentheses. We then, yeah, we then like do a second line which is completely irrelevant. And we just basically assign hello to a local variable message. So those are two messages that they refer to different things. The first is a method call and the second is a local variable. And just like before, we are passing the result of message to var, whatever message is. And in this case, we can see all we want to do is to declare a variable called message without assigning it to anything. But Ruby doesn't really require you to do that anyway. And the variable would be created whenever you first assign it. So we don't actually need the first line to do anything. Once again, we just want it to not blow up and let our code run. And if you look at the error message, Ruby is complaining that we did not have a method called message. Of course we can go ahead and define method called message but that would be cheating because we really want this to work with any arbitrarily named variables, right? Fortunately for us, Ruby has a hook for us to handle these cases and that's called method missing. All we need to do here is define a method missing that doesn't do anything. And it will capture all the unhandled method calls and suppress the errors. So with that, our code works again. The first line var message doesn't do anything and then when you run a message equal to all of it, it assigns it and then the first line uses the local variable because it's been created. So success. Let's talk about functions. This is how you define a function in JavaScript. Function, hello, fold by the function body and then when you want to call it, you just do hello, which is pretty similar to Ruby. What do you think would happen if we try to run this code? Would it just work? Would we get a syntax error, no method error, or name error? So who thinks it is A? B? C? D? Okay, of course, this is actually a trick question. The correct answer is nothing happens. As you can see, the code runs fine, there are no errors, but there is no output. Why is that? Well, let's take a look at how Ruby understand this code because this does not look like Ruby to me. Well, again, we will start from the right to the left. Here Ruby thinks that we're calling a method called hello and we're not passing any positional or keyword arguments to the method hello, but we are passing a block argument to the method hello and the curly braces actually has a high precedent, so that binds to hello instead of the other thing that we'll talk about later. So usually you would do end, but then like curly braces does more or less the same thing. So this is actually a block that you're passing to hello. And then finally, we are passing whatever the hello method returns and to this method called function, which we can rewrite for clarity like this, or maybe if we introduce a temporary variable, things will be a little bit more clear. But then there's something pretty strange here. We never defined a method called hello or method called function. So how come this works? Well, it turns out that we're being trolled by our own code. The method missing we defined earlier is silently swallowing all errors. Perhaps that was a bad idea, but it got us pretty far, so we can probably fix this. So here's what I came up with. Let's walk it through. So we know that when we are trying to define a function, we'll pass a block argument. So in a method missing, we can just see that if there's a block, we know that we're defining a function, so we can just define a method on the context class. So yes, like I said before, when we start from the right, when you call hello, it would trigger method missing, and then we'll see that there's a block and then we'll see that there's a block and we'll go ahead and define a function called hello with the block that's being passed to method missing. And then when, okay, then Ruby will call this function called, sorry, this method called function, which doesn't do anything. And finally, when we call hello, Ruby will notice that there's actually a method called hello on the current context. So it would just run that for us. And with that, we have thought, Ruby, how to define and invoke JavaScript functions, success. All right, finally, let's talk about function arguments. Of course, function is not very useful if they cannot pick arguments. So let's do this. This is how you define a function that takes an argument in JavaScript. So function hello, and then you can take a name as an argument and you can use that inside the function. And of course, when you call it, you would pass the argument into the function as you would expect. So what do you think would happen when we try to run this code? Would it just work or would it give you a syntax error? Maybe an argument error this time or perhaps a name error. Or I would even give you the final option, maybe nothing happens again. So let's see some hints. A, okay, no hints, B, C, D and E. Okay, we have a pretty even distribution among C, D and E. Well, well. I'm glad that I got you thinking about these completely useless problems, but I am out of time, so you would have to figure it out on your own. This is, there are actually a lot more cool stuff from the gem I would like to show you, but I can only fit so much into a half an hour talk. If you find this interesting, we should chat like at the hallway track. And like I said, the code is available on the internet on GitHub. You can also find a link to it from the RubyGems page. The version on GitHub actually does a lot more than what I just showed you here, and it is actually surprisingly robust for what it is. I mean, I wouldn't write production code with that, but you can do a fair amount of JavaScript-looking thing in Ruby as it turns out. And we even have tests. And so I heard that if you want to make your encouraged ability to contribute to your open source project, you should write tests and good documentation. So I have both. Hopefully you would contribute to this project now. At this point, you're probably wondering, why clearly this is completely useless? And you're probably right, but well, why not? As programmers, I think we're often too caught up with building something useful, and it is very easy if we get to have fun sometimes. We probably all started doing programming because we had a lot of fun building things on the computer. And I think it's very important for us to not lose that passion over time. So this is basically me coming up with ridiculous ideas on a Saturday and essentially playing a single player mode of code ping pong with the Ruby interpreter. And that actually kept me amused for a really long time. It's almost embarrassing to admit that. As an aside, I actually learned a surprising amount of stuff about Ruby and JavaScript from doing this. For example, did you know how Ruby actually distinguished between the local variable and a method call when you don't use parentheses? Or did you know what happens when you try to have a return statement within a block? Surprisingly, I can actually point you to real places in the Rails code base where these knowledge has helped me to understand the code and fix bugs for better or worse. While these particular piece of knowledge might not be very useful to you, my point is, I didn't really start out with the set goal to learn about these specific things in mind. So it just happened organically along the journey. So chances are when you do something like this, there will be some nice surprises for you and they might be useful to you later on without you realizing it upfront. So go spend some time with your computer and of course it doesn't have to be silly things like this, but basically just go build something build something that's fun for you. If you are into collecting magic cards, maybe you can build a thing that scans your card and like use artificial intelligence to recognize the card for you. Yeah, so hopefully you'll learn something new from doing these kind of exercise, but most importantly, I hope it will help you find a passion you have in programming again. And if nothing else comes out of it, you can at least go to conferences and make people listen to you for half an hour. So that's all I have. And finally, please remember this. If Shen can code, then so can you. Thank you very much.