 Oh, hello. I am Brian Sambodin, originally from Panama, then Columbus, Ohio, then Scottsdale, Arizona. So, yeah, I've been going from tropical to winter to the desert. And today I'm going to be talking about Mac Ruby. And why I think Mac Ruby in the Mac platform, it's the perfect combination for the beautiful language that we all love, Ruby. So, in the past, I built a lot of Windows applications. I built them with Visual Basic, with Delphi, with PowerBuilder. Every tool that was under the sun during the client server era, I've used. Some with some success, some others, not so much. And Windows applications, as you can see, I have a Brazilian favela as a background in here. Because it doesn't matter. It doesn't matter how beautiful your Windows app is, you're in a bad neighborhood. There's an inherent lack of desire for the platform to look and feel correct. Many of you have probably flocked to the Mac because of that. I don't see anybody with laptops, but there's one. So, here's one data point. I've also built a lot of Java applications. Actually, most of my adult career has been on the Java platform. And, you know, I have to be grateful to the Java platform for everything that it did for me, but now I can bash it because I found things that are much better. So, Java platform, Windows desktop applications, like, you know, Swing or AWT-based, are well-known to be pretty slow. Clunky. They're also pretty ugly. I didn't build that one, by the way. I'm letting it pass by because I don't want it to ugly-fy my slides. So, we, as Rubyists, want to have beautiful desktop applications. Desktop applications that bring the best that the underlying operating system in the hardware platform can provide. We all see applications like iTunes. For example, in the Windows world, Excel and Word seem to be the flagship applications that everybody tried to imitate. And they're still pretty damn ugly. Not to say that they're actually usable. They're not. So, something like iTunes seems to be the end goal for anybody building a modern desktop application that mixes the abilities of the web and the abilities of the platform. If you try to build something like iTunes on a browser, we know what the results are. It's typically an application that has a very heavy JavaScript site to it. And they seem not to last very long out there. So, web applications would like them to be beautiful but simple. Desktop applications that we're going to have, you know, want to look like the cockpit of an F16, where we're doing, for example, things like software development, but we want them to be reliable, robust, and also beautiful. So, Apple has basically this dogma that designed it's basically job number one. And I kind of stole that from Ford. Of course, in Ford's case, it might be a complete lie because if you ever driven a Ford, you know what typically happens. But at Apple, that design vision cascades down to the community. So, Mac developers, Coco developers, they like to build beautiful applications. And it's actually hard to find ugly Mac applications. Mostly are experiments that will never see the light of day. So, Apple is really good at mixing form, function and gluing all that together with beauty, which is where I want to go. Now, that's not beautiful. Under the covers, there's something sinister and dark. And I don't mean to install any small talk developers, but when you have C in small talk and they go out on a date, they drink way too much scotch, the next morning, you're going to end up with a pretty, well, nine months down the line with a pretty ugly child. That child, it's objective C. Now, in college, I had the choice between going with C and C++ or Pascal. And actually I went with Pascal because I could read it. I didn't have all the symbolic gibberish that you find in C-based languages. And given Ruby, it's a C-based language, but they actually did away with most of the ugly things and ended up with a syntax that it's pretty easy to read in a language that's very enjoyable to develop with. So, it doesn't mean that just because this came from C, that it has to feel and look ugly. But objective C does feel and look ugly to me. Actually, I used to write a lot of code in Lisp and Scheme. And I find that enjoyable. But when I look at objective C, I see this half-baked blend of the two worlds that just really confuses people. The message passing, it just doesn't feel very natural. It feels like a bolted-on syntax on top of C. So, as Ruby is, we would like to use Ruby to build beautiful Mac applications. Here's an example of what you find on the web about people that actually like to bash objective C. And it is a very powerful platform, very powerful language, but it has a pretty heavy RAM hub curve to actually get to learn it. And the main problem that I have with it, besides the ugliness, it's the verbosity. This is an example of how to generate a signature with PHP, an MD5 signature, and how to generate it with objective C. And you can see that the verbosity of the code, you know, it prevents you from really understanding what's going on. So, the veridict, it's that objective C, it's way too verbose to do anything in a rapid prototyping environment, anything where you want to see results, anything where you want to do, for example, something TDD. And with Ruby, now we can bring the frameworks of Ruby to do TDD in a cocoa environment. So, Mac Ruby. Mac Ruby, it's just another Ruby that happens to run on the objective C runtime. In the goal for Apple, actually, Apple is the sponsor of Mac Ruby, so it's not a third-party organization trying to jerry-rig something into the platform. So, there's a full support of Apple behind Mac Ruby. And it's a Ruby 1.9 implementation, which is also very good news for us that had to deal with 1.8.6, 1.8.7, 1.9.2. Going back and forth, every time I do anything metaprogramming related, it breaks in one of those three. So, I'm trying to stick with 1.9.2 for everything, and Mac Ruby started on the 1.9 branch. So, one of the goals for Apple is to make Mac Ruby a first-class citizen of the platform. So, objective C and Mac Ruby are living side-by-side as languages. The runtime is still objective C, and Mac Ruby is seamless integrated with that runtime. And it's really fast. And it's something that not many Rubyists kind of boast about to their frames. It's like, yeah, I'm doing Ruby because it's really damn fast. No. You show them the code and they're like, oh, wow, I don't care if it's slow because this is beautiful. Well, with Mac Ruby, you have this combination of speed in the Ruby language under the covers. You have also seamless access to objective C. And once you see some of the objective C code, you'll realize why we need Ruby to make it palatable. So, how many of you have done any objective C programming? All right. Well, that's a big contingency. Of those of you that have used objective C, how many do you really enjoy objective C? Get out. Just kidding. I had my share of ugly languages that I love, so it doesn't really matter. And the last element that Mac Ruby brings to the equation is DSLs. So, in Mac Ruby, we have a DSL-ish library called Hot Coco. And with Hot Coco, you can actually build UI interfaces. That's redundant. You can build UIs programmatically. And I will see the non-programmatic way to build UIs and how to handle events and all that with Ruby. So, like I mentioned, one of the nice things about performance in a Ruby VM, it's that on a desktop application, you don't have the ability to say, okay, we'll just add more servers and scale it. You don't have that luxury. So, you need a fast runtime to actually have desktop applications that are friendly and enjoyable to use. In a Mac, it's one of the lead developers of the project. So, let's show you a couple of things with Mac Ruby from IRB and then we'll jump into Xcode to show some more code examples. So, in Mac Ruby, every Ruby command you're used to starts with Mac. So, if I want to use IRB, I will type Mac IRB. And one of the things I want to play with, which is typical in most of the Mac Ruby demos, it's basically use the scripting bridge, which is a library that allows you to programmatically control some of the Apple applications that have scripting support. So, let's start with the number one victim for scripting, which is iTunes. And to get a hold of iTunes, the application, I use this class called SB application, and I'm going to retrieve the application by its identifier, which is COM Apple iTunes. You know, it would be nice if I actually load the scripting bridge. Another thing that you will notice with Mac Ruby, it's that everything that you need to deal with the Mac platform, it's pretty much built in. So, I can load frameworks by using the framework keyword in the name of the framework. So, now I should be able to initialize iTunes again. Then, why don't I figure out what the current track happens to be? And, of course, it's just an object. So, let's see if it's, does it have a name? Let me see. Let's look at what methods we have available. And one of the things with Mac Ruby is that all the classes inherit from Objective-C classes. So, you have a mix of Ruby, Ruby includes modules that have been included into the classes in parent Objective-C classes. So, by passing through and through to the methods command, I can actually see what methods are specific to the Objective-C part of this object. And I'm also going to subtract the methods that come from Object. So, I don't see all the root methods that happen to be in the root of the class hierarchy of Object. So, I should probably do something prettier. So, let's put this in a variable. Let's sort that in and it's hard to type turning your head. And no, I normally don't use variable names like that. If you want to avoid that return value, we do that. Okay. So, let's see what we have. So, we have quite a bit of methods. So, let's take a look at the artist. And as you can see, the artist is nobody. So, let's see if we actually have a song selected. Let's find something weird here. Of course, this is what happens when you try to do a live demo. Let's give it a try again. It should not need to be played, but that's strange. Let's try that again. If there's any bad language, oh, yeah, you're right. I'm sorry. And of course, I can control the plane or pausing of that. Now, let's do something else. Let's actually talk to iPhoto. So, here is my iPhoto instance. Let me just grab the first photo on the last imported album. And now, unfortunately, I don't seem to be able to script the preview app, but I can always use the power Ruby in bypass all that. My photo should be popping up somewhere. For some reason, I don't see it. I love it. I'll fail with error, blah, blah, blah, blah, blah, blah. Oh, yeah, I know what I did. So we have, let me see, first photo, properties, the path of the thumbnail. Do I need... Feel free to jump in and help me. There's nothing more fun than watch a presenter sweat while his demo is not working. Okay, so imagine that I am the scripting framework, and there's a picture. All right, let's move on to more fun things. So, as you can see, Mac IRB feels just like IRB. Mac Ruby really feels just like Ruby. Except that you have the ability to control the Mac OS, use every framework in library that's under the covers, and you can also sell your apps on the App Store and make a lot of money. Be rich, travel Ferrari, typical dream of every programmer. Yes. For most of the scripting automation ones, when I bring up the app, when I bring up an instance of the app, it seems to launch the app, so you see it bouncing on the bar and all that stuff. I'm pretty sure there's ways to do that silently or headless. I just haven't gotten to that point yet. Oh, by the way, I am by no means an Objective-C expert. I'm an expert on a lot of things that kind of look like Objective-C, and I've done a lot of desktop development, so this is to me a brand new world, too. So I want you to get excited, as I'm excited right now, that I can actually finally build beautiful desktop applications with Ruby. So there's two ways to build applications with Ruby, with Mac Ruby. One, it's programmatically, and I mentioned the HotCoco framework or library that allows you to basically position elements programmatically, determine how those elements are going to cover certain parts of the screen, how they're going to resize, things of that sort. In some environments, for example, when I used to do swing development, that was my preferred way to actually build UIs because the tools were really clunky and just left you with a bad taste in your mouth after you put the code together. They also generated code. So the problem is that they were a one-shot tool. You generated the code, and then you had to actually go and manually change things to make it work correctly just to keep up with the limitations of the tool. So now you had something that was machine-generated, but yet you have to maintain. And that always bothered me. Then in other environments, you have a binary representation of the UI of some sort, and then you hook up to it from the code so you really have a very clean separation of the view from the models and controllers. With Objective-C in Coco, you have sort of a slight combination of both. There's some presentation-based wiring that goes into play in the actual view file, but it's very minimal. It's basically the ability to have aliases to be able to talk to different parts of the UI from your controllers. There's also, and this is very hard to see, lesson number one, always use light backgrounds for everything in a presentation. I just couldn't pass on these pictures, but you can see that there's a carpenter doing things by hand, so that's a problematic point of view. There's also Interface Builder, which there's a bunch of machines back there where you can't see them. So Xcode, it's the environment that all Mac developers use to build Mac applications. And it has a UI builder, which is actually pretty usable, and it's been around for a long time, so it has a lot of time to mature and become a very reliable tool. Xcode also supports Ruby to an extent nowadays with Xcode 4. It's no Texmate. The Ruby support is still kind of goofy. I would say it's still quite experimental. For example, if you highlight a block of code and you do an Apple slash, you're thinking it's going to comment that block of code with Ruby comments, well, you're going to get C comments in there. So things like that, there's little details here and there that need to be improved. So Xcode now has, on Xcode version number four, has support for Mac Ruby applications built in. So it's no longer like a wiserty for you to try to figure out how to get your Ruby application working in Xcode. So you can pick a Mac Ruby application and it basically provides a skeleton for everything that you need to get started with desktop development with Mac Ruby. So this is a preview of what the interface builder looks like. And as you can see, it has a graph paper-like type of UI where you place components. You have a main window for your application and you will place your components and arrange them and lay them out in a way that satisfies your application. There's also a lot of building objects in interface builders, built library. So we have all kinds of buttons and control sliders. Also components that are used for automation with other applications. You can see that there's ways to control scanners in video devices and things of that sort. But we're going to play mostly with the visual controls today. So what I want to build in front of you, which can go horribly wrong, it's a very simple web browser. And the web browser, of course, we're not going to build the rendering engine for a web browser, otherwise we would need a couple years of time for the presentation. We're going to use WebKit, which is the built-in connectivity to the WebKit library. So there's a WebKit web view that allows us to use the WebKit library to manipulate a embedded browser in an application. We're also going to have a home button, which we all know what it does, and a back and a forward button. And I'm going to show you how to build that application, connect everything together, and use Ruby to handle all the important events under the covers. Now, there's something slightly goofy about this example, which I did this example before without a single line of code, which you can do in Interface Builder, because there's ways to connect everything in ways that you can bypass all of the code. So for our example, I'm actually doing all that wiring and handling of events in the Ruby code so you can see the mechanics of a Mac Ruby application. So what we're going to do is use WebKit. We're going to lay out components on the main application window. We're going to deal with something called outlets and, of course, events and actions. I'm going to do some logging, and we're going to build the application so we can have an executable that we can give to our friends and say, hey, use my crappy browser instead of Safari or Firefox. So let's do some live coding. Mystery Science 3000, anybody? No? Cavit Amter. So let's get started. And, of course, I have a cheat sheet to be able to do this correctly. And I'm going to turn on the mirroring so I don't have to be turning my head for this example. Of course, I have a completed version of this application on my computer, and it's also on GitHub so you guys can go get it and play with it. But let's do a brand new one. So I'm going to, in Xcode, which, by the way, this is what Xcode looks like, I'm going to create a new project, and I'm going to select the Mac Ruby application project. And let's call it Mac Ruby Browser Live. And you can see that if you're familiar with Java, the namespace in Objective C and Cocoa and the Mac platform is very similar to what they use in Java. You can see here that my company identifier is already pre-filled. And you can determine which category you want to label your application to be under in the App Store. So the whole App Store stuff is now really baked into the development environment so you can have a very easy transition from finished, compiled, built product to the store. So I'm not going to pick any categories because this will never see the light of day. And you can also create a document-based application where you would have more of a built-in model under the covers for you to deal with certain aspects of the application. But in this case, we're going to ignore all that. There's also core data which allows you to basically use the local file system as a data store source. Being a Ruby application, we could also use things like ActiveRecord if we wanted to in a simple embedded database. So that's the beauty of this. We can take all those gems from the Ruby world to actually help us in the Mac world. We can have truly complex models, database-driven models if we wanted to. Compatibility issues? Yes, they are not all gems work on Mac Ruby. The way that I find which ones work, it's to basically try them. I believe there's a list somewhere. I just haven't gotten to it yet. But the majority seem to work. Objective C also, the runtime can also deal with C++ and C. So in most cases, things will work, but it's not guaranteed that they will. So after I created a new project, I need to pick a place for it to live. So I'm going to put it under my projects folder on my documents. And as you can see, now I have my new project open in here. I have the definition of my project. I have the frameworks that the project is using right here. So you can see that Cocoa framework in Mac Ruby have been brought in. And I have something called an app delegate. And the app delegate, as you can see, it's not an Objective C class. It's a Ruby class. And it has an attribute accessor for the window and the skeleton placeholder for an event handler called application-did-finish-launching. Now, Objective C names are pretty verbose and long, and they actually follow camel case syntax. So you can get queued and try to change that because then the hookup of events in here, it's being done based on the name. So you're going to see, one of the things that bothers me about Mac Ruby is that you see this combination of Objective C methods in Ruby methods. Now, the J Ruby guys did a very incredibly smart thing. It's that when you bring any Java methods into the equation, they get converted to Ruby syntax. So they get underscores in all lower case. Why that wasn't done in Mac Ruby, I do not know. But it's one of the few things that syntactically bugs me a little bit. So you can see in here that that method, it's a Ruby method and it just doesn't have anything inside of it. So there's also an RB main file, and this is the file that it's used to actually launch the application to launch the application as a Mac Ruby application. That RB main Ruby, it's also invoked from this main, the M Ruby, I mean Objective C class, or sorry, C class. And you can see here that it's invoking RB main, with whatever arguments are being passed, and that's going to invoke our RB main, that it's actually loading Cocoa, and loading all the files that you need, the main file name, and executing the application. So let's actually start building the UI. And of course I have, for layouts, here's my cheat sheet, what goes where and how to align it. So let's get started by sizing things so I can actually do some work. Notice I'm going to click on this view so I can see the object library, which is down here. And from there, I'm going to pick first a NS button. All this NS classes are next step classes that are Objective C classes. So I have this component or control called a square button, and I'm going to drop my square button on the UI, and I should not do that, because that button is floating on nowhere. You have to select the window that you're going to work on. So as you can see, I don't have much screen real estate, but there's my main application window. So I'm going to try this again, grab my square button, and I'm going to drop it somewhere on my application. One of the things that I want to do to that button, it's actually style it a little bit. And what I'm going to do is change the image on that button. So notice that I clicked on the attributes inspector up here, and I'm going to find the image attribute for that button right here. And now in that image attribute, you can see that there's a drop-down, and it'll give you a lot of different choices, like what you use for a color panel for a computer. I could not find the one that I wanted for the home icon of the browser. But if you try things, they typically work. So I typed NSHOME in there, and that actually happens to be the image. It won't refresh it at development time, but the first time you run it, you will see the button in there. So let's go ahead and run this. Notice that I failed the build to... What did I do? Okay, I delete that and run it again. Did I leave it sitting out there? Oh, there it is. Thank you. Okay, let's make sure that this builds with nothing in. Nope. Something it's not like any today. Great. All right, so this is plan B. Things go straight to hell. You bring the application that's completed and working. And instead, I'll do a walkthrough through the application. So here's the UI that I built for this, very simple. Notice in here that that's my home button. I have a text field in two round texture buttons. In Interface Builder, I can change the names of the buttons directly on the interface. So there's a lot of things that you would not want to do in code. But for example, if you were using some kind of bundling technique using a Ruby library, then you could still get to those buttons and change the language of the buttons from the Ruby code. So this kind of throws off my whole cheat sheet. So some of the things that I want to show you here, first of all, so here's my application again. And notice that when I click on the home button, I have a action that's being sent from the Go Home action. It's linked to this app delegate, which is the Ruby class that we've seen before. Now also, if you look at the... There's a reference in Outlets, so I could map different elements of my UI to code in the Ruby class. So if I open the app delegate, notice that, for example, I have something called URL bar that I added as an attribute accessor. URL bar, of course, like any other instance variable in Ruby, it's going to be accessible in the code as at percent URL bar. Now, if you look at the connections for the URL bar, you can see that I linked the load page to the app delegate. So that basically what I'm doing in here with my outlets, and I'll show you here a quick example. If I were to try to connect the reference in Outlet to the app delegate, it tells me what do you want to connect it to. So in this case, I'm going to say that's the URL bar. And that's how you create connections between the UI and your Ruby code. Now, to be able to load content, I created a couple of methods. One, it's called go home. And the go home method, it's going to use the built-in Objective C logger, which is the class NS log. And you can pass a Ruby string to that. And then I'm grabbing that URL bar, and I'm setting the string value of the URL bar to a URL, just Google.com. And then I'm calling a method that I wrote in here called load page, passing the sender that was passed to that method. Now, in load page, what I'm doing is accessing the main frame of the WebView. Now, you might ask yourself, what is the WebView? If you look back at the UI, there is a component called WebView, which I took from the WebKit library, which is the only component that's available there, and that is a WebView. So basically, a full-blown browser in a Objective C control that can be placed on any application. Now, inside of my WebView, I connected my WebView to the app delegate. So the at percent WebView in my code, it's pointing to that WebView. In the code, then in the load method, I'm getting to the main frame of the WebView, and I'm loading a request. And of course, as a Rubyist, to find out how you can do this, you would have to actually look at the Objective C documentation. It's all online, and there's a lot of how-to articles in there. So there's a lot of searching involved with learning Objective C if you don't have a guide of sorts of some kind of book that you're following. But I seem to be able to find most of the things that I need just by searching the library. So in here, I'm using this NS URL request. I'm requesting a URL with the specific string that actually happens to be in the URL bar. So I modify the application that finished launching to actually go to the home page immediately. So the application launches, I go to the home page. Then I connected the events, go back and go forward to the go back and go forward methods in the WebView, and I attach those to the buttons. If we go back to the UI, and I pick the back button, for example, you can see that the action go back, it's being sent to the app delegate. In the back button, it's referenced in the app delegate. Now, let me show you a couple more things in here, and then we'll launch this thing. So I show you how we go home, how we load a page. Let's actually view those in a running application. And hopefully this should work, because it worked just five minutes ago. And somehow we'll realize that was something very stupid that failed before. So here's my little browser. Very little work in terms of basically laying things out. I've probably lost... No, the Wi-Fi seems to be working. No, it's not. So Google's new page, it's so simple that it doesn't have any text on it. It's beautifully simple. Well, I deserve that for trusting Wi-Fi connection. But trust me, it works. And you can get the code from GitHub and check it out. Some of the things that I did in here, I made the URL bar text field the driver for the whole application. So whatever URL goes in there gets reflected on the WebView. If we go back to the code, there's also a couple things that I had to do to be able to keep that text field as the driver for the application. So one of the things that I had to do is figure out a way to change the address of the page that was loaded. So if somebody was navigating on the browser, I need to capture those events and then change the URL that's being shown. And I did that with this method. So notice me here that the method starts with WebView. Then there's a parameter called WebView, and I did start provisional load for frame, a colon in the word frame. So it looks very non-ruby-ish, very strange. It's valid ruby, but it doesn't look very ruby-ist. So inside of that method, I'm putting a log message, and I'm checking that the frame is actually the main frame of the browser. And if that happens to be the case, I'm setting the string value of the URL bar to the absolute URL of the frame that's being loaded. Now, you might ask how did you figure out how to write that method? Well, the first step was to actually Google for how to refresh or how to get the title or the URL of the page being loaded. And of course, I got a snippet of Objective-C. And I'll show you what that snippet looks like. Hey, the word's never wronged through, huh? So here's the Objective-C method that I found. You can see that there's a dash, return value, it's void. There's prefix with the word WebView in a colon. So that's what you see in the name of the method WebView. The WebView parameter, it's basically the sender that we see up there. And the didReceiveTitle has two parameters. One, it's a title, and then there's also a forFrameFrame parameter. So the syntactic sugar that they use in Mac Ruby to be able to bring that type of method signature into Ruby was to use colons. So you can see that I have the didReceiveTitle. Of course, I don't need types because we have an untyped environment. And I have my title and my frame. Also, you can see some of the strangeness of Objective-C when you see all the brackets on the inside of the if. So all the message passing, it's done with nested brackets. So in this case, they're sending the window message to the sender, and then they're sending the setTitleMessage to the result of that. So it's kind of like dot notation but with brackets, which I don't know what they had against dot notation since it was a C-based language, but that's a topic for another day. Now, so what we did was to interact with WebKit. Sorry, one of the things that I forgot to mention, too, is that if I run the applications as it was before, it also wouldn't work because I needed to actually add the library. And if you look at the definition of the application, you'll have to add the WebKit framework in there. So from here, you can have access to basically all the built-in frameworks of the Mac platform. So there's a lot of stuff in here that you can start playing with, and that's sort of how I've been discovering Mac Ruby by actually loading a library and see what methods are in there and playing with the code. I got the Ruby part down, so now it's basically the process of discovery of Mac Ruby. We have the URL on GitHub where the code lives, and I'm going to keep on adding more and more everything that I experiment with. I throw up in GitHub. There's hundreds of Ruby projects in there, hundreds of Java projects in there. Just ignore those. And soon to be a lot of Mac Ruby projects in there. We also use a native logger, and I can show you that there's an executable. Well, you get it. There's an app that you can basically now drop into your applications folder and anybody can use it. So basically you have a native Cocoa application that is being controlled by the coolest language that we know living on your Mac. And I can already see an explosion of Ruby-based development tools probably built with Objective-C in Ruby Cocoa, in Mac Ruby, and it's an interesting time to actually be on the Mac platform. There's a few books out there. I got the early release of those two books, Mac Ruby in Action in Matt Imonetti's Mac Ruby, The Definitive Guide. This one so far it's really good, and it's all available online for free on the O'Reilly site. Thank you very much. Any questions? Yes. Sorry. Next question. No, Mac Ruby actually uses the garbage collector. So the iPhone and iPad applications are not allowed to basically touch that part of the infrastructure of the system, so not yet. But I hear rumors that things are changing for the better. So I'm tempted to say that in the next six months we might see some announcements regarding Mac Ruby on the iPad and iPhone. Yes. This is what I've been using. Well, all the Ruby class, I mean, you can build your own RDOT from the Mac Ruby source. I don't know that somebody has posted online somewhere so everybody can get it for free. But maybe that's something I'll do. I have a few servers laying around. But the Ruby, it's still just Ruby. It's the Objective C part that you're going to have to basically look up and then do the translations like I did from some of the Objective C examples to the Ruby examples. And that took me a little bit of time figuring out how the dynamic of converting things. I don't know if somebody can actually write a parsing tool that can actually do the conversion for the method signatures. That would be probably a very nice thing to have. Any other questions? Yes. Same here. I have the same problems with understanding Objective C syntax method, the way they think about passing messages to objects. Nothing that it's a clearing house. Yeah. There's not a clearing house of basically all information for Mac Ruby. So if the Mac Ruby website has a lot of links to different things. But you can see a lot of DS sales appearing around the complexities and ugliness of Objective C. Like for example Hot Coco, it's a library that basically wraps building UIs programmatically with Mac Ruby. So it looks completely like Ruby. There's nothing weird in it. And the more I imagine the progress of the platform is going to be that people just build directly by touching the Objective C classes, but they start writing basically libraries that encapsulate some common behaviors. And eventually you're going to have DS sales wrapped around all the Objective C ugliness so we can be completely shielded from it. You still have to go and understand it because you're really talking very close to the metal of development in here. And UI development is that way. You really need to understand what the control that's under the covers, how it behaves, how it works. There's also going to be probably memory allocation, the allocation issues that you might have to deal with in complex applications. So things like that, you will start seeing libraries or DS sales wrapped around complexity in little areas like that, just like Rails did with web development. One more question. Well, I actually... The first desktop app that I bought through the App Store was Xcode 4, which actually then I discovered it was free. But somehow you paid 5 bucks to buy it from the App Store so you can get updates and stuff like that. So I'm going to write a letter to Steve to get my $5 back. But other than that, it seems to be an explosion of applications. It's growing fast. It's not as big as the iPhone Store or any of those iTunes stores. But it's growing. And I think they have a very high level of standards to let applications in. So you're going to be again in a good neighborhood. Thank you.