 I'm very glad to be here today and welcome, please thank you for attending this session. So this session is about Mac Ruby. It's a version of Ruby that runs for the Mac, especially for the Mac. And my name is Laura Sensoniti and I work for Apple in the core operating system team. And forgive my horrible French accent, please. And so today's agenda is very simple. First I would just give an overview of what Apple and Ruby is doing. And then I will focus on co-code development with Ruby because it's a very important feature that we want to promote. And then I will do some demos and then there will be some time for questions, I hope. And we really love Ruby at Apple. And Ruby started, it started in McWestern since 2002. It was 1.6, one of the first versions, and then it was updated. And more recently in Lopart, we are shipping Ruby Cocoa, Ruby Gems, Rails, and which is kind of cool because since Lopart, we are supporting co-code development with Ruby. So you can write co-code application in pure Ruby and we provide compatibility across future OS releases. So if you write an application now, it won't break with the next versions. And for the future, we would like to ship Rails 2.x, whatever, the latest version, passenger, and we are interested in Mac Ruby, of course, which is the main topic of this talk. And our goal is to make McWestern the best platform for Ruby developers. And to do that, we need to make Ruby a first-class citizen in McWestern. And to do that, we need to make Ruby a first-class co-code programming language in McWestern. And this is the very important part, I think. And why are we focusing on Ruby right now? It's because Cocoa, the big framework of McWestern that you use to write co-code applications, is mostly written in Objective C. And Ruby and Objective C are conceptually very similar because they both inherit from small talk. So they are both dynamic languages. You can, you send messages. You can reopen classes at runtime. You can create new classes at runtime and things like that. But the key is that Ruby is pure interpreted while Objective C is compiled. So it's really cool to associate both runtimes because you can do things in Ruby that you can't really do in Objective C. And in 2006, I gave a presentation here, not here, but in Denver, about Ruby and McWestern, especially about how we bridge Ruby and Objective C. And Matt's right on this blog that after seeing this, we end up feeling wasn't Ruby made for McWestern. And this is really what we, most people at Apple have been thinking the same. Because the Objective C runtime and the Ruby runtime are very close. And by the way, the computer in the background is not a Mac. I don't know what kind of computer it is, it's black. Anyway, it's not Matt's computer, right? Sorry, I picked this picture on Google, so that's not yours. And this is the world development stack of McWestern. And it has four different layers. The thing is that every layer depends on the layer above. And the Darwin layer is the core of the OS. It's completely free. And it includes the kernel, but also the Lipsy and some C APIs. And then we have the graphics and media layer, which is all the OpenGL and core image stuff. You can use that if you want to customize animations or to custom graphic stuff. And the application framework is the most important layer. It's in this layer, we'd find cocoa. But you will also find things like address book or a search kit or things like that. Frameworks that you want to use to build your applications. And then there is the user experience layer, which includes things like spotlight or quick look. And it's there if you want to improve the global user experience. But the nice thing is that these four layers are written in C and Objective C. And in Leopard, we are supporting them in Ruby. And we are supporting them with a project called Ruby Cocoa. And Ruby Cocoa is a bridge between C and Objective C versus the Ruby 1.8 runtime. So it means that from Ruby, you can call C APIs and Objective C APIs. So Objective C is purely dynamic, so it's very easy. But for C, C is completely static. So to do that, we have a project called Bridge Support, which documents all the static APIs in XML files. And then at runtime, we reconstruct the Ruby APIs. So you can access C constants, C function pointers, C structures. And you can call any C function that you want. And we are using FFI for this. And this version, the C runtime can call you, can call Ruby. And this is a very old project written in 2001. And it has been rewritten recently to be stable. And it's been led with macOS 10.5, and it's supported. So you can use it today, and it won't disappear. But for many of you who have Macs here, you can raise your hand. Oh, that's a lot of people, except Matt. And how many of you are familiar with Mac development in general? So do you know Coco? Not so many, maybe 10 hands or 15 hands. And that's true, because if you're looking at the consumer applications written in Ruby, there are not that much. I think there are only two applications. There is Limchat, an IRC client, and Blogo, which is an application to write blogs. And both are really cool applications and are written in Ontario and Ruby. But it looks like Ruby developers don't want to write Mac applications. On the other side, if you look at the web development in Ruby, how many of you are familiar with web development in Ruby? That's mostly everyone, I think. Well, not those people in the background. And that's completely true, because there are many, many web applications that are using Ruby, many consumer applications. I just picked some applications on Google. I don't know really if they use Ruby or not, but that's very different. And why exactly? So besides the fact that the web market is definitely bigger than the Mac market, and not everyone on Earth is using a Mac yet, I think there are two big reasons. The first one is that Cocoa is a very hard framework to apprehend for Ruby developers. It's a huge framework. And the problem is that Cocoa was written for Objective C, and especially it uses very verbose method names, which are completely different from Ruby APIs. As an example, if you want to write code to show this Hello World window in Ruby Cocoa, so not in Objective C. So it's a very simple window with a title, and then there is a button. And when you click the button, it says Hello World. And you have to write that, which is very, which is huge. Is it really Hello World? And building the window looks very complicated. And then you have to create the button. And the problem is that when you create a button by default in Cocoa, it's not the Aqua button. It's a square button, like in Java. And if you want to connect some code, when the user clicks a button, you need to create an Object, define a method on the Object, and then you need to pass the Object and the name of the message. And this is very complex to use for most people, I think. And the second reason is that Ruby 1.8 and Ruby Cocoa have some performance and design issues to be used intensively inside Cocoa. And the first problem is that it's a bridge. So Ruby 1.8 and Objective C are two different runtimes. And we need to bridge them. It means that if you want to access Cocoa Object from Objective C in Objective C from Ruby, we need to create a proxy object that will forward the messages. It also means that every time you pass an Object from Ruby to Objective C, it has to be converted. This is extremely costly. And also, every time you create classes in Ruby, we have to create the same classes in Objective C. And this is Versa. If you want to access classes in Objective C, we need to create the equivalent classes in Ruby. This is very complex to maintain. And we have lots of problems with Ruby Cocoa because of that. The second problem is that the messaging syntax is different. In Objective C, methods argument can have names. So there is some kind of method argument names in Objective C. And in Ruby, there is no support for that. And I will come back to this problem later. The third problem is that the Ruby 1.8 runtime has green threads and is not re-entrant. So the green thread problem means that there are lots of problems with Cocoa. Because Cocoa expects you to call from different POSIX threads. And there are so many bugs because of that. So we have to act the runtime. And it's very ugly. And the second problem is that it's not re-entrant. So you cannot really call the Ruby 1.8 runtime from different threads. You need to log every time. It's a bit of a problem. And finally, both runtimes have different garbage collectors. So this is very complex to maintain when you have a bridge and two different garbage collectors. It means that one garbage collector has to rule the other. And also, it's an increase in memory. And the answer to all these problems is MacRuby that we created earlier this year. And MacRuby is Ruby 1.9, re-implemented on top of core macOS 10 technologies, like the Objective C runtime and garbage collector, and the Core Foundation library. Core Foundation is the foundation of the foundation framework. So basically, it's a very foundation framework. Like, every string that you create in Cocoa are actually core foundation strings. It's a very basic of everything on all the frameworks. And it has been in development since a year. Actually, it's a pretty young project. But we want to release the first production ready version by the end of the year. By production ready, I mean you can really use it to write applications. And MacRuby is meant to solve the Ruby problems. The Ruby 1.8 and Ruby Cocoa problems. And where is the bridge? Since we are using the Objective C runtime, there is no bridge anymore. Because when you create a class in Ruby, it's automatically an Objective C class. There is no need to create, to maintain the different class model between the two worlds. And every time you create a Ruby method, it's automatically an Objective C method in the runtime. And we use the Objective C runtime to dispatch calls. So even if you do, you write a method in Ruby and call it. It will go through the Objective C runtime. And finally, every Ruby object is an Objective C object by default. So there is no need to convert types. This is very good for performance. And in 2008, February, Matt said just after we announced the MacRuby project that if MacRuby succeeds, there is no doubt Ruby will establish itself both in name and in reality as the official scripting language of OSN. And this is really true because we are not talking about a bridge anymore. The language is really based on the CoreS technologies. And by the way, Matt still looks the same in 2008. And it's still not a Mac in the background. And so this is Matt's Ruby 1.9. So I separated it in five different parts. You have the parser, and then you have the YARF, which is the virtual machine. And then the runtime is responsible to dispatch calls and things like that. And also allocate memory. So it has the garbage collector. And then you have the built-in classes, like strings, array, hash. And then you have the standard library, which is already a big library. And MacRuby today looks like this. So we modified the parser to support name arguments so that you can call Objective-C in a very nice syntax. On the other side, we didn't do the YARF because we think it's a great virtual machine. On the runtime side, however, we reward the runtime so that we use the Objective-C runtime and we use the Objective-C garbage collector to allocate and collect memory. So it's a completely different runtime. And the built-in classes, although we reward them so that every string that you create in Ruby is a core foundation string. Same thing for array and hashes. And on the STDLib side, we didn't modify a single line in the standard library. So we can run, for example, IRB or Rake. We start to run gems. And we are including a library called Otcoco, which I will discuss a little bit after. But let me show you some demo. So first, I'm starting Mac IRB, which is IRB, the same IRB. But we are running it via Mac Ruby. Oh, can you, I can. OK. And the funny thing is that, whoops, that's better. So it's Ruby, by the way. And the funny thing is that in Mac Ruby, so all objects are actually subclasses of the NS object, which is the root object of Coco. And, for example, even a fixed name. A fixed name is actually, in Mac Ruby, a subclass of the NSNumber class in Coco. And if, for example, I create a string, then I ask for a class. It says it's an NSMutable string, which is weird, because it's not string anymore. And if you type string, it says it's NSMutable string. So actually, it's true. So it's an NSMutable string in the way you can mutate the string. In Coco, you have mutable and non-mutable objects. So this is my string. And I can call, for example, upcase. That works. But if I ask for the encoding, which is a 1.9 method, it says it's a Mac OS Roman encoding, because the string is only ASCII characters. But if I ask for the encoding list, to get a list of all encodings, it is whoops. OK, let's try again. Oh, that's better. And this is the list of all encodings that we support through the core foundation framework. And the nice thing about, if you ask, for example, the method on the string, you will see that it responds to all the Ruby methods. But we saw that we have this NSMutable string class. So we don't show the Objective-C methods by default. If you want to see them, you need to pass the second parameter as true. And here we have lots and lots of methods. That's all the methods a string can respond to. And that's a lot. And if we want only the methods for the string class, we can strip them. And we can see that we have lots of methods that are quite strange. But for example, if I, for example, like uppercase string, if I go foo.uppercase string, I get foo. So it's exactly the same method as the uppercase Ruby method that you know. But there are some methods with semicolon in the name. And these are the Objective-C methods that I was talking about. So for example, there is strings by replacing occurrences of strings with strings. So this method will replace all occurrences of the given string with the other given string. And we can try that. If I do helloRubyConf, and then I can waste string Florida. And you say, hello Florida. So here we are calling an Objective-C method. But we are passing two Ruby strings. The funny thing is that these are cocoa strings. So they are not converted. And calling this method is as fast as calling a Ruby method that you would actually define. And the funny thing is that all strings in MacRuby so are cocoa strings. And in Core Foundation, all strings are using ICU to apply transformations from one Charsa to the other. But they can also convert characters. And if I type Arigato and then transform Latin to Irogana, I get some kinds of bytes. And actually, this is a Unicode byte. So if I put them, I see the Japanese string. And this is really cool. This is really a Unicode string. It's SUTF 16. And so since we are on MacRuby, so we have access to all the cocoa frameworks on the system. And there is a nice one called Scripting Bridge, which is an Objective-C framework to communicate with applications through Apple events. And the main class of this framework is SB applications. And if we ask for the methods, you can see that this class responds to these methods. And let's try to connect to iTunes, for example. Oops. Ah, iTunes. And here we go. And the funny thing is that Scripting Bridge creates Objective-C classes on the fly when you actually provide the bundle identifier. And but in MacRuby, there is no support. We don't need to support that. Because we are really native to the runtime. So there is no need to create proxy classes. In Ruby Cocoa, it's really a pain to maintain this framework. And now that we have the application, we can ask for the current track. And it says it's an iTunes track. If I look at the class of this object, it says it's a track which inherits from iTunes, which is an SB object, then an NS object, and then it includes the Carrier module. So this is funny. This is really a pure Objective-C object that we are working with on IRB. There is no Ruby stuff there. And I can ask for the name. Oh, this is Daft Punk. And these are all the methods that our application can respond to. It's not that much. And there is the Play-Pose method that should start iTunes. It works. And you can pose it, replay, or it's 100. You can choose the volume or stuff like that. But whoops. So if we go back to this method, it returns a string. But the funny thing is that if we ask for the class of the string, it says it's an NS string. So it's not an NSMetable string. But it's still a string in Ruby. The fact that the frame is that you cannot really transform it. And if I do strip, for example, it will say, ah, you cannot modify the immutable string. So in order to modify an NS string, you need to make a mutable copy of it. And there are methods for that. Oops. And I think that's all for the IRB session. I think we have time to, I'm going to create a small UI for this code. So now I'm going to demonstrate the Xcode integration with Mac Ruby. So let's start with a new project. I will call the iTunes controller. And here we have our controller. And hey, I'm not lucky today. It's not working. I don't know what's happening. It looks like my computer is completely crazy today. Open this one. Oh, I still have this project. And this is a, I wrote that a few minutes ago. But it's funny that I cannot create new projects. It might be a bug in my machine. But this is a Cocoa application written in Mac Ruby that actually controls iTunes using the scripting bridge. And here we have the framework scripting bridge call that I just did in IRB. And this is the line that I type as well to get an application, the iTunes application. And here I have all my actions for the user interface, which is here. So I have a labor here. Then I have play, stop, previous, next, and then the slider. It's really bad that I cannot demo that. And anyway, the application works. And I can play. You can control the volumes and things like that. So it works, but I'm sorry. Yeah, it's really too bad that it didn't work. So we have Hot Cocoa in Mac Ruby now. And Hot Cocoa is a thin Ruby layer on top of Cocoa. And it's actually a builder-like API to allow you to build UI components using Ruby syntax. It's very elegant. And it's written by Rich Kimmer, which is somewhere here. I don't know. It's here. Thank you. And if you remember the Ruby Cocoa Hello World sample that I wrote, and if you want the Mac Ruby version, it's actually only we only have to change two lines. But the rest is still the same. It's still Cocoa. But with Hot Cocoa, it's better because you have to write that. It's way, way better. So for example, when you want to build a window, you call the window method. And you buy some arguments, and it will create your window. And if you want to grant a button and then connect an action, you pass a Ruby proc object, a block. This is really rubbish. It's not Cocoa anymore. It's hot. And if you want to know more about Hot Cocoa, you should see a rich session tomorrow. And in the future of Mac Ruby, there are three things that we would like to do. First of all, we would like to have multicore support. It means that we want Mac Ruby to use all the cores of your CPU. So to do that, we have to rewrite the runtime so that it can be completely re-entranted. So it's a very big challenge. And on the second time, we would like to introduce just system compilation somewhere in the virtual machine. And finally, we would like to make Mac Ruby an OSC language. OSC stands for Open Scripting Architecture. So it's really the base of upper script. And if we make Mac Ruby an OSC language, it will be the same as upper script technically. It means that in May, for example, you will be able to write your main rules in Ruby and not in upper script anymore. And it means that you can also control applications natively and not passing through a bridge anymore. And maybe in 2010, Mac Ruby said, I'm a Mac. I don't know. If you want to know more about the project, you can go to the macruby.org website. And we have a Twitter account now, macruby, if you want to track the project or things like that. And don't forget the hot cocoa presentation of Rich tomorrow if you want to see how hot cocoa works. And that's all. Do you have any questions? OK. Sorry? I can't hear you. I can't answer this question. I'm sorry. Next question? Yeah? On the, when you're doing the Xcode app and showing the Ruby, I know you didn't do any outputs. Are those just automatically macruby? Yeah, so it's really too bad that it didn't work. But yeah, you don't have to specify outputs anymore. You have to create a access source. Ruby access source will be outputs by default. And actions will be methods with the standard parameter. So it's completely transparent now. Yes? Who else is working on macruby with you? Sorry? Who else is working on macruby with you? It's only me right now. Right now. Yes? You said that you wanted to see this added to OS 10 possibly in the future. Yeah. Would this replace the macruby interpreter? It will be an additional project. We cannot replace a mac interpreter because it's Ruby 1.8. And we cannot break compatibility. Yeah? Any more questions? Yeah? So macruby, how difficult would it be to say take the core of macruby and just compile it with the GCC effect to see? Take the core of macruby and recompile it? And just say take it on Linux and compile it with GCC effect to see. So it should work, except that the Garbage Collector has not been ported yet. So once we have the Garbage Collector, it's going to be, we would like to release the sources of the Garbage Collector soon. So once it will be released, then we can make a port in Linux and even in Windows. Yeah? Ruby spec, run on macruby? I don't know. I think that it works. So the M spec project can work with macruby. And that's all I know. I would like to run the Ruby specs project as well, because it is great. But currently, we are trying to stabilize the project. So first, we get stable, and then we start to pass the test. Are you at 19 specs, which is what you would run? Oh, they are already 19 specs? Oh, nice. That's great. Well, thank you.