 Next up is Eric Michael's over. He is the second post handsome Ruby programmer in the world. He is going to talk to us about GUI programming with McRuby. GUI programming is a sticky situation, so I hope that he provides some clarity. Okay, GUI programming with McRuby. Hey everybody, so my mother is a journalist and when I was very young she instilled in me this idea that there's only a handful of words in the English language that you can use to ask a question and if you answer all those then there's no questions left to be answered. So I'm basically going to run through all these points on McRuby and if there's any questions at the end I'll just take that as a personal affront to my mother. These are the only questions. So first, who? Who the fuck am I? This is my given name, but you might know me on the internet as SF Eric, Twitter, GitHub, Gmail, IRC, etc. And I'm currently in the middle of a one-year fellowship at a non-profit organization called Code for America. Yeah, Code for America. We're working to make government more efficient and transparent and open. It's basically the best thing ever. I get paid to write open source software all day in Ruby and you can too. We just opened up applications for our 2012 fellowship. So if anyone's interested in that, come often talk to me at some point during the conference and I can give you more information and give you a t-shirt as well if we have great t-shirts. So I also write a lot of open source code, not necessarily related to fixing government. You probably use at least one line of code that I've written at some point. So you're welcome. And right now I'm actually, so just to be clear, I'm not a McRuby expert. I've never submitted a patch to McRuby. I'm not on the core team. But I am currently developing a McRuby app called Hubcap. And basically it's a social GitHub client. So I think like a third-party Twitter desktop client, but it's just for your friends to write code. So you can keep tabs with them and see what code they're writing. So these are the real heroes for McRuby. You should follow them. And there's also the last thing on the list is the McRuby develop mailing list, which is really active and great place to start if you're interested in diving in and getting questions answered. So as the who, now the what. What is McRuby? So McRuby is a few things, but first and foremost it's a complete implementation of Ruby 1.9. So you can think sort of just like JRuby except instead of running on the Java virtual machine, it runs right on top of macOS core technologies. So it runs on the Objective-C runtime, uses the Objective-C garbage collector, which turns out to be vastly superior than the Ruby garbage collector even in Ruby 1.9, primarily because it's multi-threaded. And so garbage collection can happen on a separate background thread, so it never is interfering with your main thread. And there's no global interpreter block in Objective-C. So it has great performance just like in the same way that JRuby has great performance. It also uses LLVM, which is Apples. It's not really a VM in the same way that the JVM is a VM. It's more like a compiler infrastructure, but it uses that to compile code into Objective-C bytecode. And there's both a JIT, just-in-time compilation process. You can use IRB the same way you do now, and it'll work great. And there's also a ahead-of-time compilation process, so you can bundle your applications and ship them out as packages. So yeah, so this is sort of the diagram, this is what it looks like. All Ruby apps should run in the Mac Ruby interpreter. Not everything that you write from Mac Ruby will run in every other Ruby interpreter. And I just want to give a really quick, this is going to be the most simplistic demo. And it's not getting into any of the GUI features at all, but it's just sort of proving that Mac Ruby is what I say it is, a real Ruby. Can you guys see that? Let me see if I can get it off. I'm trying to get cinched to work, but that's probably useless. Okay, let's make that bigger. Another one, cool. So, demo is always fun to watch people sign up for, right? It's great. Okay, can everyone see that? Those are basically side-by-side, similar size and big enough font and everything. Yeah, cool. Well, that'll work. So, I'm using RBM, and on this side is 192. And on this side, I'll make it Mac Ruby. So, this is the latest version of Mac Ruby, 0.10. And I'm just going to open up IRB in both of these. So, looks about the same. And if you have a string, Ruby 19, and you have a string in Mac Ruby, they're totally the same, exactly the same. Okay, great. And if I ask for that string's class in 19, anyone want to venture a guess as to what it's going to say? Stream. Great. And anyone have an idea what it's going to say on this side? It is a stream. Wrong. So, that actually changed, I think, between Mac Ruby 0.5 and 0.6. It's actually going to say string. So, I just blew your mind. I know. But what do you think is going to happen if I say, Mac Ruby.class, that's super class on this side. Correct. Object. Good. And any guesses for this side? So, some people said NS object, some people said NS string. You're both wrong. Correct. Somebody knows their stuff. It's an NS mutable string. So, the super class of a Ruby string in Mac Ruby is an NS mutable string. Anyone know if I super one more time what I'm going to get? Correct. So, you get an NS string. And if I go up one more time? Great. So, everything is an object, or everything is an NS object, is the case maybe. But basically anything you can do in Ruby, you can do in Mac Ruby. So, let's say I want to capitalize that string. So, I can say, food out of case. Okay. Food out of case. And over here, I can do the same thing. Right. So, I can say, food out of case. And I get a big, my fingers just do what they want to do. You get capitalized food. So, that's cool. And if I want to see what methods are on string in Ruby 1.9, I can just say food out of methods. Right. And you're going to see almost exactly the same list. It's not 100% identical. But it's basically the same list here. I can sort them. So, make it so you can actually do one-to-one comparison. So, it looks like there's a few more, like, there's this, like, rational thing that's going on on the Mac Ruby side. But they're basically the same. In theory, they're the same. But what's really cool in Mac Ruby is you can do this. Right. So, I can say, methods true, true. And the first true, I can do one true on this side. Right. So, if I say true there, does anyone know what that does? Yeah. It's going to do the same thing. It's a Boolean that says, include all the methods that are in all the superclasses as well. And so, by default, that's true. So, you're going to get the same number of methods. Right. What's that? I do it with, sorry, it's really hard to see from this angle. So, yeah, if I say false, then there's nothing. If I say true here, I get the same methods. But if I say true, true, if I give it the second thing, what you can't do on this side. Right. I do this and we'll say, wrong number of arguments. But if I do this over here, what it'll do is it'll give me all of the Ruby methods that you can call on string. It'll also give me all of the Objective C methods that you can call on an NS string. So, if I say methods.size for foo, it's going to give me 168. If I say methods, true, true, size, it's going to give me a lot more. Okay. And let's just take a look at some of those and see what they are. So, they're these ugly, these ugly Objective C things. But what's cool is that you can actually call them. Right. So, just like I can say foo.upcase, I can say foo.uppercase string. Because Objective C is all about being concise. And it does the same thing. It totally works, right? You can invoke methods in the normal Ruby method invocation way. And so, that might not seem awesome, but it's awesome. Because you have all the power of Ruby. You can call any Ruby method. And you can also, you can also call any Objective C method. And you can mix and match, right? So, you can have classes that inherit from NS object or NS mutable string or anything like that. And extend those using Ruby. So, I think that's really cool. But that's not really the fun stuff. The fun stuff is Julie programming, which is what this talk is all about. So, if I can figure out how to resume the damn thing. You can learn a little about that, too. What's the keyboard shortcut to just, oh, there we go. Is that playing? Okay, great. Do you think H, it goes to your desktop? Or do you just grant that back to it? Okay, thank you. This is probably all complicated by the fact that I'm running the line developer preview, which I'm not allowed to say anything about. But you can take from that what you will. Okay, great. So, Matt Ruby, in addition to being a complete implementation of Ruby 1.9, also lets you do two other things. So, one is you can write scripts to control existing GUI applications. So, if you want to write some script that updates your status in iChat or, you know, that does anything, really. Like, you can basically use it in the same way that you use Automator for the map. But with the full power of a real programming language, like Ruby. And then you can also create new GUI applications, right? So, that seems like an exciting thing that you might want to do. But why should you care, right? Like, there's already a language that exists to script map applications. It's called Apple Script. And there's already a language for creating new GUI applications, or new map desktop applications, called Objective Safe, right? So, what do you need Ruby for? So, I'm going to tell you a secret. I need everyone just to lean in because I can't say it on the mic. Listen carefully and lean in. The secret about Apple. It's like real juicy. So, here's the secret. Apple's not very good at making program languages. Who is good at making program languages? I think this guy is. So, why do I say that? What's not so good about Apple Script? Well, Apple Script is really a toy language, right? It's not object oriented. It doesn't have blocks. It doesn't have regular expressions. It doesn't have most of the features you'd want in a real programming language. And sort of the things you just take for granted in Ruby. So, I think it's pretty fair to say that, you know, given equal ability, you know, you had to choose fairly between Apple Script and writing an application in Ruby with MapRuby, you would choose MapRuby. MapRuby has a great scripting bridge framework. So, you can use that to really easily hook into any application and write scripts to your heart's desire. But maybe you're thinking, you know, I don't really care about writing scripts. For other people's gooey applications, I want to create my own. And for that, Apple has a language for you called Objective-C. And Objective-C is not a toy language. How can you tell that it's not a toy language? You look at the name and you see that it has the word C in it. And so you say, okay, this must be a very robust, powerful language because it's C. And that's mostly true. That's mostly true. But I think I would sort of make the case that it's more hampered by being constrained by the syntax of C than it doesn't really give you any additional power. And what's nice is that because MapRuby uses LLVM and compiles your applications down into Objective-C bytecode, you get all the performance and benefits of Objective-C, the power of C, but you don't actually have to write C code and deal with C. So I'm just going to try to make the case that Ruby is better than Objective-C. It's just a nicer language. So let's just look at method invocation. So this is how you invoke a method in Ruby. It should look familiar to everyone in this room. Can anyone suggest how you can make this simpler? This is a real question. Any ideas? So you could get rid of the dot. Someone said, get rid of the dot. But then how would you know that... You put a colon after a method. Right. So you could get rid of the dot, but you need some other syntax, right? If you were to get rid of the dot, you wouldn't know that Object wasn't a method that had two parameters. I guess you would because there wouldn't be a common between them, but it would be hard to parse what those three things were without the dot, right? I mean, I'd be interested to see the parser that would be able to parse this as ObjectMethodParam without the dot. Not saying it's not possible, but yeah, that's true. Getting rid of the dot would make it simpler. Okay. So this is how you do method invocation in Objective C. And I think this is kind of gross, but, you know, maybe it's not so bad. Can anyone think of a way to make this simpler? Okay. So lose the semicolon. Yeah, you could get rid of the semicolon. I agree. And I would say, basically, it would make it look like the Ruby version, right? If you wanted to make it simpler, you could basically do that. But you can't do that because Apple was bound by C syntax, and so everything that's, every all Objective C code ultimately gets compiled by GCC. It has to be syntactically balanced C. And so they made it look like this. So this isn't so bad, right? Maybe you say, I could live with this. It takes a little adjusting to, I got to remember if we put semicolons at the end, but no big deal. So this is sort of exited B. So this is Ruby again. The title's wrong. This is Ruby, right? Should look familiar. And this is how you initialize and sign an array from Ruby. Suggestions on how to make it simpler? Cricket. Pretty simple, right? Hard to imagine. Too much simpler. This is how you do the exact same thing I've definitely seen. So, you know, I, like, if you are okay with doing this, then Objective C is the language for you. But I think if you're a Ruby developer and you want to, like, for me personally, the thing that got me into MapRuby in the first place was I basically have been spending my whole life writing shell scripts, things that work on the command line, you know, maybe web services and things that have an interface in HTML and CSS. But the idea of being able to code in a language like Ruby and generate something beautiful like a desktop application seemed out of reach because you had to do a lot of stuff like this before MapRuby. And to me, MapRuby was the thing that sort of gave me that entry way into the GUI development. Right, so somebody said, yeah, don't forget you have to release that too, right? You're doing an alloc in there and you have to release that. Although, it's garbage collected, so you may or may not have to release that, but you have to sort of worry about it. So Ruby Cocoa was Apple's first attempt at supporting Ruby. So they built this bridge, they built this Ruby to Objective C bridge and you can make an application that looks like this. This is the implementation of that little program in MapRuby. And it's using a really nice DSL written by Rich Kilmer called Hot Cocoa. And, again, I would sort of challenge people in the audience to say, if you want to make something that looks like this, right, this is what you want to produce. Give me a simpler, give me a suggestion on a simpler way to produce that than this Ruby DSL. Any ideas? I mean, you should tell me to Rich if you think of any because it would make them better, but I think this is really simple, I think this is really nice. We can just go through the code line by line, but basically, you're saying make a new application, right, and then you say, make a window, you can give it some attributes, we're giving it size, and then make a button, give it a title, right, so that's going to be the text that's on the button. And then when you do the action on B, the action for a button is pressing it, we're going to put the word world, okay, so we're just defining that there, and then we attach B to the button to win the window. That seems really simple and nice to me. I really like Hot Cocoa. Just for doing really simple apps, it's great. So this is the same version in Ruby Cocoa, which was Apple's first attempt at allowing you to bridge, to write Ruby code for desktop development. This is the exact same app, right, so this is this, in Hot Cocoa. Sorry, in Ruby Cocoa. So Ruby Cocoa is a shitty language, even Apple thinks it's a shitty language, they're not working on it anymore, and they're actually investing a lot into Mac Ruby development. They're paying developers full time to work on it, and putting a lot of support behind it. So Apple finally, maybe, will be in the class of companies that make great programming languages, right? But there's other ways, right? If you want to write a client for the Mac, a lot of different ways to do that, right? So, you don't have to use it in a room full of Rubyists. I'm not going to spend a lot of time convincing you not to write Java apps for desktop clients. I think you guys sort of know probably been seeing that movie, been down that path before. So the promise of Java is that write the code once, runs anywhere, right? And you're even going to deliver that promise, but there's always something that seemed wrong about Java client apps, right? There's always something that was not quite right about them. You couldn't maybe put your finger on it, but just something seemed wrong. So, you don't get that in Mac Ruby, right? Mac Ruby apps look and feel exactly the same as apps written in Objective-C because they are native Cocoa applications, right? They sort of showed earlier in the demo on the command line, Mac Ruby objects are Objective-C and they use core foundation and other core underlying Apple Objective-C frameworks and services. And so, yeah, don't write Java apps. Java wasn't the solution to write once, run anywhere, right? The solution to that was the web. And so maybe you're thinking like, okay, I could use one of these fancy new JavaScript frameworks for doing these rich, rich apps in JavaScript. And I'm not going to tell you not to write web apps. You can do that, but I write web apps all the time. Web apps are awesome. But not all apps have to be web apps and there's certain things you can't do on web apps, right? So, I have like a Bluetooth device if I want to write a Mac app that communicates with my Bluetooth device. If anyone knows how to do that in a web app, I'd be interested to hear it. But there's just certain APIs and certain capabilities that are offered to you in MapOS 10s APIs that just aren't in web APIs, right? Okay. So, that's sort of the what. The when. This is exciting. So, just yesterday Mac Ruby 0.10 was released. It's a great release. It's stable. 1.0 is coming really soon. Features have basically been frozen. So, the core team has said they're not really working on any new features before 1.0. They're just polishing up the APIs. They're going to do maybe a couple small releases just to improve stability and performance leading up to a 1.0 target. So, that's awesome. And Map Ruby whatever version of it is the latest at the time presumably hopefully 1.0 will be included in MapOS 10. It's already included in the development previews. The only problem with this is that currently it's a private framework, right? So, if you want to use Map Ruby in your app, you have to bundle all of Map Ruby into your app. You can't just assume it's there in the operating system. If Lion made this public framework, then you would be able to assume it was there at least for Lion. So, that would be great. There's a lot of discussion in the mailing list trying to figure out how what sort of developers can do to make it a public framework. But, basically, if you have to bundle Map Ruby with your application you start off with a 50 megabyte footprint of your application before you write a single line of code just for bundling Map Ruby. So, if it was a public framework and you could assume it was there, then every Map Ruby application would be 50 megs smaller. So, that seems like a worthwhile thing to do. Do you guys feel like advocating for that? That would be great. So, why? This is kind of the last question. Why? So, I think I already gave you some reasons from a programmer's perspective. I think hopefully I convinced you that the syntax is nice and if you want to use it, then if you want to build a Ruby application, then Map Ruby is a pretty good way to do that. So, here's a number of reasons why. One is you already know Ruby. If you're sitting in this room there's a pretty good chance you know more Ruby than you do any of the other languages I mentioned as candidates for writing Google desktop applications. That's a good start. Number two, you can use any existing Ruby libraries. Ruby libraries that you've already written is VAS, Gems on RubyGems.org and you can use those in your Ruby application. The other thing is Map Ruby is all 192. Especially if you're bundling the application then you can just use like the cool new hash syntax in Ruby19 and not have to worry about breaking anyone's code. It's sort of nice. You can use all the nice syntactic features that are in the latest version of Ruby. As I mentioned earlier, there's no global interpreter lock. So it has the potential to be really fast for that reason. It also has a much better garbage collector than even in the latest version of Ruby. Mostly because it's multi-threaded. Because it can run on a background thread in memory without delaying any tasks in your main thread. So it's really fast. Here's some benchmarks. The X axis is confusing. They're just a bunch of different benchmarks and it couldn't figure out how to rotate them so that they'd be vertical so you could actually read all of them. But each one of those bars is a different benchmark. That yellow line across the middle everything's sort of been relative to Ruby 1.9. So if you see for everything that's like a 4 or a 5 or a 6, that means it's 6 times faster at doing that benchmark than Ruby 1.9. So not everything is faster, right? There's certain things that are slower. But I think this makes it pretty clear that in the main map Ruby actually outperforms Ruby 1.9 for doing most sort of things that you do in benchmarks. And that's true in practice. You're not taking a performance hit at all by writing your app in that Ruby. And many times it's a performance game. I think a lot of people would be well-served to run their existing non-map Ruby applications, right? Just any sort of Ruby application on that Ruby just because it's such a fast Ruby. Same way that J Ruby is a fast Ruby. And then here's another reason, right? So the Mac App Store is a huge new opportunity for map developers, right? I think Pixelmator said they made a million dollars in the first 20 days of sales on the App Store. And so that's an amazing statistic. And you think, oh, well, maybe I should do an iPhone app, maybe I should do an iPad app. Those are much bigger markets. And that's true. More people have iPhones and iPads than have Macs. Maybe that's not true with iPads, but it's going to be true really soon with iPads, right? But that's offset by the fact that Mac users are willing to pay more for apps, right? And you can sort of deal more with apps, like being limited to the screen real estate of a phone is an interesting design constraint and people have made amazing iPhone apps and iPad apps. But there's certain, you know, I'm of the opinion that, like, I have an iPad, I love my iPad. To me, it seems like something that I use in addition to my laptop or desktop computer, right? It's not a replacement for that. At least not yet. So there's a great opportunity to sort of cash in on this wave of apps. And there's also a lot less competition, right? So the app store for iPhone and iPad have been around with all these existing apps. There's a lot of competition. This is a great space where, you know, before there were all these barriers to writing Mac desktop apps, now those are sort of going, those barriers are going down I think it's a great time to to do this. So how do you how do you get started? You can go to MapRuby.com and download it. It's just a package, right? Like any other Mac, DMG or maybe ZIP slot. But you just go through and install or it works. If you're running RBM just make sure you have the latest version of RBM installed and then just say RBM install MapRuby. And I would make sure that there's a 20 gig broadband pipe. So if you all want to put that to the test now just type the two commands on your screen. There are a couple dependencies that you'll need first. You may already have them. So one of them is LLVM which you can install either if you use homebrew with homebrew or with Mac ports like that. You can also build it from source if you're one of those people. And you also need to ask for tools which you probably already have, but yeah, so that's where you can get that if you don't have that. And so like what are some of the other resources you should know about if you want to get started, right? Download everything. What do you do next? There's a great book that Matt, I mean that he's working on now called Ruby the definitive guy. It's an O'Reilly book and he's writing it like live on the internet so you can see every time he updates it. It's totally free. So just go check it out. It's a really nice book like the first nine chapters are mostly fleshed out and he's sort of filling it in and updating it as new releases of Mac Ruby come out. But that will presumably be published pretty shortly after Mac Ruby 1.0 is live. Yeah, there's another book which you can get early as well. So Mac Ruby in action hasn't been published yet, but you can pay 20 bucks and get a PDF of it in whatever state it's currently in. And it's another great book that I'd recommend as well. And despite what I said about Objective C earlier, having a knowledge of Cocoa will help you, right? Because you can call any methods in Cocoa and Mac Ruby. Having a really fundamental understanding of what's happening under the hood helps and this is an awesome book for understanding how Cocoa works. So I would highly recommend that. And if you have any feedback about the talk feel free to send me an email or a tweet or something like that and you can follow me on github. If you don't have a computer, you can call me. My telephone number is 415 212 2382. That was a joke. Don't call me. And that's it. I think I have exactly like one minute for questions. One minute. I have two questions. First one, RubyGems and they're not compatible but that has a native retention of violations. Does anyone work on that? And second one, distributing an app that is using a not mined era. Right. So I'll repeat the questions for those who can hear it. So the first question was what about gems that aren't compatible? So if gems aren't compatible that's arguably above, right? Even if there's native extensions, if there's the extensions, then in theory Mac Ruby should be able to handle those. So that's like and I think like even in JRuby now they're working on solving that problem. So if you find a gem that's not compatible with Mac Ruby, we'll install. You should file that as a bug and yeah, I mean that's a bug, right? Like the diagram that I put up earlier with the circles should be true, right? Any program that works in MRI should work in Mac Ruby. And then the second question was about the bundling. So if somebody doesn't have line, like let's say that Apple decides to make a you basically just say include or require I'm not even sure how you actually would say it but if they expose some interface that says like you can include this and you have the whole staff so you don't have to bundle it what would you have to do on earlier releases of macOS 10? And the answer is hopefully they'll also when they do that release version updates to Snow Leopard or whatever, but if not then you just have two separate binaries, right? So you could distribute a package for Lyon, it would be a very lightweight package it would be 50 and I'm smaller and then for everything before Lyon or you could just say we only support Lyon and it would break on anything before Lyon. Great, I think I'm out of time is that right? Yeah, okay great thanks everybody