 Welcome to the Mac RubyMotion presentation. I'm very happy to be here today. And just one thing, I really like Seattle, so it's a very nice city. But you guys have too many coffee shops. So I can't go to each of them, so we need to return eventually. So yeah, this is a presentation about RubyMotion. Just a few things about me. Yeah, Shane just said it, but I'm a longtime Ruby enthusiast. I've been using Ruby for about 10 years. Before doing Ruby, I really liked Per as my favorite I-level language, but I realized Ruby was a better alternative. So I decided to stick with Ruby. And I work on a few things about Ruby, like the Ruby GNOME 2 bindings, which are Ruby wrappers for all the APIs of the GNOME desktop. Then I did Ruby Cocoa, which is the bridge between Ruby and the Mac runtimes. I did a bridge between Ruby and Apperscript called Ruby OSA. I think it's dead now, and you shouldn't use it anyways. But when we did Ruby Cocoa, the goal was to make sure that you could write full Mac applications in Ruby. But it turns out that it wasn't possible with Ruby Cocoa, so there were so many problems, performance and stability issues, just related to the fact that it was a bridge, some sort of middleware between two separate frameworks. So I stopped working on Ruby Cocoa and I did Mac Ruby, which is supposed to be a better Ruby Cocoa. But Mac Ruby is different in the sense that it's a true Ruby implementation on top of Objective C, so it's no longer a bridge, so it works much better. Yeah, I'm a programming language nerd, so I like programming languages. I really like that. My last employer was Apple. I worked for a few years there on iLife, OS then. I work on the Unix layer, so it's basically what powers Macs and even iOS devices these days. Yeah, I was responsible to introduce Ruby Gems in Leopard, but I'm not responsible for the fact that Mountain Lion ships with Ruby 1.8, so it's not my fault. It's not my fault, so you need to blame the other guy now. But I left my job at Apple to do a startup. I left my well-paid job in Silicon Valley to do a company, which is crazy, right? But yeah, it reminds me of what Shane said yesterday. So quit your job and do something better or different. So if you're working for your employer and you think you can do something different, I think you should take the chance and do it. Especially a startup is very, very funny. So Ruby Motion. So I think that you guys probably heard about Ruby Motion. How many people heard about Ruby Motion here? Okay, there are people who don't know what Ruby Motion is. So, Ruby Motion is basically Ruby in your pocket. So that's the title of the presentation. So it's basically a toolchain that lets you write applications for iOS devices, such as iPhone or iPad or even iPod Touch, but using Ruby, only Ruby, exclusively Ruby, so no other languages. So why would you want to do iOS applications? I mean, you guys are already Ruby programmers. You probably use Rails on a daily basis. So why would you want to do mobile apps? Well, it turns out that it's a very recreative market. At the latest WWDC, Apple announced that they sold more than 365 million iOS devices since the very beginning. They also say that there is something around 400 million iTunes accounts. Of course, there are more iTunes accounts than iOS devices because people use iTunes on different platforms. But I think it's safe to accept that most iOS devices are actually connected to the iTunes store, to the App Store. So there is a huge market and a huge opportunity to create applications. And because of that, there is a huge demand for iOS developers, especially in the considerate business. At the same time, it's also possible to make pretty good money just by working on applications, publishing your apps in the App Store. And the great example is Paro. It's an email client written by friends of mine in France. So they sold the company to Google. But their investors leaked some information on Twitter. They said that Paro was generating something like $60,000 per month, which is nice for an email client. So it's perfectly possible to make pretty good money just by doing applications of the store. And there is no technical reason why Paro could not have been written in Ruby with RubyMotion. So what RubyMotion is basically Ruby as a language, but we implement it on top of iOS. It's also statically compiled, so it's very different from the Ruby implementation you probably use today. The entire tool chain is actually based on the terminal. So there is no UI. You don't need to learn anything new. You just get to use the terminal. And you also keep using your favorite editor. So it doesn't come with an IDE. So that's actually a design goal. And finally, there is an amazing community. So I'm going to go through these five points very quickly because we only have 30 minutes. So the runtime. A very interesting thing about RubyMotion is that both RubyMotion is Ruby and Ruby and Objective-C are actually using the same technologies, the same foundations. So what does it mean is that when you reuse RubyMotion, when you create a class, it's actually going to use the same machinery, the same foundations as if you create a class in Objective-C. So a class in Ruby is the same thing as a class in Objective-C. It's actually using the Objective-C runtime under the covers. So when you create a method in Ruby and you pass an instance of that class, that would respond to that method to an Objective-C API, the Objective-C API can call that method as if it was written in Objective-C. So there is no bridging thing happening. Everything is truly native. And at the same time, the building types of Ruby, such as string, array, and hash, have been rewritten on top of foundation types. Foundation is a framework that ships with iOS, and the framework comes with basic types like NS strings, NS arrays, and NS dictionaries, which are the same thing as array, string, and hash in Ruby. But in RubyMotion, we decided to rewrite these classes based on their foundation counterparts so that when you use an API in Objective-C that expects an industry, you can simply pass a string to create in Ruby. So again, this is really for performance reasons. So we don't want to convert objects when you try to use the APIs of iOS from Ruby. And this old design is actually, I call it the unified runtime. There is only one runtime. When you use RubyMotion, it's the Objective-C runtime. So it is very different from bridging technologies where you tend to have a different programming language with a different VM, a different garbage collector, a different set of classes, and a different object model. And then you get the native platform that you want to access. And this is very similar to our experience with RubyCoco. RubyCoco was that sort of thing. It was a bridge between MRI or CRuby, which is called these days, and the Objective-C runtime. It was very painful to keep both object systems alive at the same time, and caching objects when you cross the bridges. And here with RubyMotion, it's really native. So an application written in RubyMotion is truly the same as an application written in Objective-C. If you look at the code that's generated, it goes into the same APIs at the very end. But you would say, why should I use Ruby? I mean, if there is already Objective-C, you could just learn Objective-C. And the thing is that Ruby is much more concise. Well, I'm not going to explain that to you. You already know that. But this is a very basic award in Ruby, a basic class, and with an accessor, and you can initialize the class, and then you can code the same method. And the same thing in Objective-C would have been written like this. As you can see, it's already twice the code, more or less. For about the same thing, I mean, just printing a message in the terminal. So there is a lot of boilerplate code that you need to write when you create a class, when you create an accessor. Of course, you also need to keep two separate files, one for the interface and one for the implementation. And it can get very bloated even if it does only the same thing, like this NSLog method at the very end. We have users of RubyMotion reported that they actually converted their IS applications from Objective-C to Ruby, and they say that generally they get rid of 50% or 60% of the code at the very end. That's only when using the same API. So that's not even using a DSL or a library, just using the same APIs, like removing all the craft or the boilerplate code that Objective-C forces you to write. So that's a very cool example. So RubyMotion lets you call into the Objective-C APIs, natively, but you can also use C APIs because they are pure C libraries and frameworks in iOS. And one of them is OpenGL. OpenGL is purely C, so there is no Objective-C stuff there. And that's an example of RubyMotion calling into OpenGL. So I haven't written this because OpenGL is very... I can understand OpenGL. It's very tough. But so basically what's happening here is that it's actually calling the same C functions of OpenGL, but from Ruby. So this glclear color is actually a C function that you can call it as if it was a Ruby method. The compiler is going to generate some sort of stub that we call the C function. And the constants that you see, like gl underscore color underscore buffer underscore bit, it's actually a C enumeration in the header file of OpenGL. So if you're familiar with a C, it's actually described in the header files of OpenGL. But it's available in RubyMotion as a Ruby constant. And then you have all these magic things like... Sometimes in OpenGL you need to pass a magic cookie, which is a value, and you cast it into a VoidStar pointer. So I'm not going to explain, but it's basically a hack to pass some magic value into the real pointer to an object. And in RubyMotion you can use the pointer magic cookie method to do that. And so the whole thing is working. I think it's a very simple game that shows a cube that rotates and you can click on it and it divides and some sort of things. But it works so. I was very surprised to see people using OpenGL in RubyMotion. So let's take a look, let's talk about the compiler now. By the way, this is the LVM logo, which is the most awesome logo ever. Awesome, right? So basically it's called static compilation. I think that Remotion is probably the only Ruby that is statically compiled. Maybe, I don't know, yeah. It's one of them, at least. So the idea is that we take Ruby code and we generate machine code at the end. And the machine code is completely pre-compiled. There is no more evaluation, interpretation when you run the code. And everything is self-contained. So that's the goal. And in RubyMotion, applications are always statically compiled. So when you use an RubyMotion app on your device, it's always going to run the code that you wrote and you cannot evaluate code at runtime. We disabled that for, actually, for a reason because I'm not really comfortable with the Apple guidelines about that. So it's basically that it's really all statically compiled. But how does it work exactly? Well, it's Doug's programming computers. Well, no. So I'm going to explain a little bit. So first we start with Ruby. So here we can create a class, HelloView, which inner is from your issue. It has a method. That's RubyText, right? And the compiler is going to process the code into a syntax tree. So a syntax tree, as known as the AST, is basically a huge tree of expressions inside the code. So here, for instance, we have... So here it's basically an array. I'm using Ruby here as a representation syntax, but the compiler is not written in Ruby. It's basically an array. So we have a class, HelloView, then we have a superclass, then we can... Well, we have a method, so it's a DefN. We start with a new DefN tree. So it's a tree of trees. And then we have the drawWake symbol, which means that we are defining the drawWake method, and it goes on. The entire code is compiled into this data structure. If you're not familiar with ASTs, there's a gem called parse syntax, parse tree. No, parse tree, yeah. I think it was written by ZenSpider. It should be somewhere here. Okay. You mean the... You mean the 1.9 extension? Okay. There is a... Okay. Anyway, if you want to play with ASTs, there are gems, and they will give you these kind of things inside IRB, so you can see how Ruby is actually compiled under the scene, so it can be interesting. So then from the syntax tree, we actually convert it into LVM IR. So IR stands for Intermediate Representation Language. So we are actually going to compile the syntax tree into this language. So LVM has its own internal language. That is... So it let us... So it's basically an assembly language, but it's a platform or architecture agnostic, more or less. So we actually implement the syntax tree using this language. And first, the great thing about LVM is that there are so many optimization passes that you can apply on the IR. LVM comes with a huge load of optimization passes, and we apply a great deal of them. For instance, we can eliminate that code. We can reorganize if statements. We have... We have optimization for constant lookups, instance variable access. So we wrote also most of the optimizations, but we can actually reuse a lot of LVM ones. We also have an optimization for a... which is called TCO, a tail call optimization. So if you have a method that ends with a call to the same method, we are actually... We remove the call and we actually jump through the beginning of the method. So you can do a functional programming in RubyMotion, which is great. But the great thing about the LVM IR is that it's agnostic. So from it, we can target different platforms. And so we only target two platforms, Intel 32-bit, which is a platform when you run the simulator, and ARM for the devices. ARM versus 6 or 7. So we get assembly there, and so I'm not going to explain what it is. So it's basically a machine code, and it's compiled to machine code right after. So at the very end, you get true machine code from your original Ruby source code. So, yeah. So this is an app I wrote with a friend. It's called Mustachio. It's a very basic app that actually uses face recognition, and the API is in iOS to add a Mustachio to all the faces it can find in a picture. This is my kid, by the way. This is my son, Alexis. Sadly, the application is no longer in the App Store. Not because it's written in Ruby, but I forgot to renew my Apple account. So I actually used my wife's account for this app, and I forgot to renew it, so they removed the app. Which is weird, right? I mean, I didn't even got an email saying, well, we'll remove your app. So, anyway. So I'm going to resubmit it, but you can find the source code on GitHub. But the most interesting thing about this app, at least in this context, is the application size. So perhaps you can't see it, but the size is 0.9 megabyte. And it's a RubyMotion app that ships with runtime and all the source code of the app. So this is really great. So you can... I mean, the compiler doesn't add much bloat, much fat to your application. So let's talk about the tool chain now. The tool chain is all based on the terminal. So you get to use the terminal to create new project in RubyMotion. And then every project is based on rake. So there is a rake file, and if you want to change the configuration of the project, you just edit the rake file. So it's very simple. And then the rake file has a few rake tasks by default. And one of them can push the application on the simulator so that you can see in real time what's happening. You can also push the application on your device if you have an iOS device connected for development. With USB. Or you can create an archive, an IPA archive for an app store submission. But it's all based on rake. Sorry. And people have been saying, wait, wait, wait, you are using the terminal on rake. What about Xcode? I'm not sure if you guys know what Xcode is. But basically Xcode is Apple's IDE. So it's basically the IDE Apple wants you to use for iOS development or Mac development. So it's actually a great IDE for Objective-C. It's very nice. It's re-optimized for Objective-C. But for Ruby, it kind of sucks. It's very sad to say that. First, the editor is not extensible, so there is no way to add functionality. There is no debugging support for Ruby or other languages in Xcode. So if you want to write a Ruby debugging Xcode, you can't. There is no plugin interface, no API. The Ruby support of Xcode is also very poor when it comes to syntax. It's very, very bad. I'm pretty sure they use regular expressions to colorize the source code. I don't know. For instance, when you have a Ruby file in Xcode that has a regular expression, and inside the reggaps you have some sort of keyword that's defined in the Ruby language, like if, then the whole source code would be messed because Xcode, we think that the if token inside the reggaps is actually a statement in the syntax. Sorry about that. Anyways, we don't think Xcode is a great environment for Ruby, which is why we prefer people to use their own editors. And at the same time, in Xcode, you get to use the IDE to create core data models and user interfaces. So there is a way to use Xcode to create the database of your application, which is based on core data. So basically you can create the tables with your mouse. You can create the fields inside each table, the relationships. And at the end, Xcode will generate a binary that will ship inside your app. And the binary will be parsed at runtime by core data. And the same thing happens with user interfaces. You can use interface builder, which is some feature of Xcode. And you can create the UI with your mouse. You can drag views, create actions and outlets to connect the UI with your code. And then at the end, it generates also a binary that will be parsed at runtime by UI keys. But I'm not really comfortable with that because it's a binary. There is no way to see what's happening. I mean, when you put it in source control, it's very easy to break things. For example, it's very easy with your mouse to forget to disconnect something and then you just break something. It feels very magical. Like this. I have been using Xcode for a very long time. Before it was even called Xcode. It was called Project Builder. And I always feel like this when I had to use interface builder or core data. It feels too magical for me. I prefer to see what's happening. So that's why it's perfectly possible to use core data or to create user interfaces programmatically. And I think Ruby is a great language for that because Ruby allows layered abstractions. You can easily create domain-specific languages. And at the end, you can very easily create very complex UIs in code. Or you can also create database entities in code. The perfect example, of course, is Active Recorded Raves. You guys don't use an interface to create the database. You can use Ruby directly. Oops. Ah, yes. And it wouldn't be a real screenshot of Xcode without the crash window. Because it crashes all the time, sadly. So in Ruby Motion, you get to use the editor you really like. So personally, I use Vim. But they are support for all the editors. And if you go to the developer center, you will see that you can install plugins to have, for instance, auto-completion of the APIs. The iOS SDK, I mean, these APIs were designed for Objective-C. So they are super long names. And it can be very tedious to type all the characters. So they are plugins to have auto-completion. There are also plugins to interface with the tool chain so that you can, with shortcuts, run the simulator, push on the device. So it can be very handy. So they are very support for Vim, but also for a text mate, sibling text tool, which is another editor. Red Car, that's the fourth one. It's actually very nice because it's a Ruby editor written in Ruby. Using G-Ruby. So if you have never used Red Car, I recommend that you give it a try. It's all open source, and it's very nice. And then there is Emacs, which is some sort of operating system. So it's not an editor, I don't know. I have never used it because my... I never had a computer fast enough to load it. Well, I just got... So we use Emacs. Yeah, yeah, yeah. I don't know. I just got SSD, so maybe I can try it now. No, I'm joking. Well, there is support for RubyMotion in Emacs, if you really like it. But Vim is much better, I think. No? Anyways. So there is a huge community around RubyMotion. It was very amazing to see so many people using it because that's nice transition. There is more than 500 projects on GitHub. So most of these are samples. People are just working with it and doing a set of things. But there are also libraries, DSLs, and for instance, the support for these text editors were written by the community. So that's really amazing. So I'm going to show a few libraries or a project written by those folks. And the first one, which is very interesting, I think, it's called T-Cup. So it's a DSL to create user interfaces with RubyMotion. So they follow the CSS way of styling the user interfaces. So they created a DSL to style basic elements like text fields, search fields, and so on the first part of the code you can see that they provide a custom style sheet for these elements, and then at the second part they create a view controller and then they can apply the style sheet that they defined earlier. So I assume that it's going to use the same style there. So it's very interesting and their DSL is actually very... I don't think it's mature yet, so they are still iterating on it. Okay. So the RAP is another project. It aims at wrapping all the iOS APIs using Ruby. It aims at providing Ruby abstractions, so that's what I was talking about. In this very specific snippet they wrapped all the HTTP and the JSON support of iOS in Ruby. So it feels like Ruby. When you read this, it's actually using the iOS APIs. So it's a library, it's a layer on top of iOS. So it can be very convenient and they have wrappers for a lot of things. So double wrap. Another one is for motion. It lets you write this kind of UI which is very common on iPhone applications. And if you want to write this by hand, it's super hard. You need to create a table view with custom cells and if you're familiar with iOS development you know that it's very hard. And some guy created this DSL which looks like a hash. It's basically a huge hash and then it generates what's on the right side. So it's very cool. And I don't think I would have time for the demo, I'm sorry. But if you can, if you have any questions you can ask me or I can show you a demo later. And that's all. RubyMotion.com