 Who am I? I'm Sam Rollins, there's my Twitter, there's my email, github.com, github.ly, github swathons, my plans to pain the Ruby community are non-realistic thus far. Also otherwise plans to pain, nah. So a quick thing with the C extension. Okay, so MRI is the first C extension we know. It's written in C, I'm sorry, it's the first implementation of Ruby. It's written in C. I think the low level libraries written in C include fixed num, big num, strain, hash, et cetera. You might be saying, okay, fixed num is older in my ground calling. Why do I care about these old-ass C extensions? So even viewer code in MRI, 192, we can include the C extensions. So array is largely a C extension, so they add pf, dirt.home is a C extension, the fiber pass is a C extension. So Ruby must be able to talk to the expansive world of C libraries, the vast array of C libraries out there, normally being taken seriously. So if you try to see extensions API, it's basically the Ruby value each file is in a formal extension API. I think Matt's wrote a little de-oxygen document on some of them. Then there's the pay tax. So that's kind of all the APIs. So if some of your favorite gems are C extensions, these include most of the traditional C-fold gems. Not the newer C-fold stuff. Those usually communicate. Nukagiri, JSON, FASTA, et cetera. So I did a quick look at RubyGems.org. So this is as of a couple of days ago. They had about 21,000 gems. Only 415 are extensions, and I'm very okay with that because of course in Ruby, not everything should be an extension. So there's a few here. But amongst the top 100 downloaded, 18 are C extensions. I think that's a pretty high percentage. I was surprised by that. So the top 10 most downloaded C extensions you can see. I'm sure some of your favorites are on here. JSON. Your favorite is on here. That's kind of neat. So motivations for writing a C extension. There are two motivations. I think more than 95% of C extensions are motivated by the following two reasons. One is speed. So C code compiles down typically the faster machine code than Ruby language and Ruby code compiles down too in the Ruby byte code. And two as a bridge to an existing C library. And then many C extensions are mixed with both of these. So two good examples are Zlib, and I mentioned it over here. So Zlib is this old, old C library. It's called Zlib, I think. And it is vetted. It has, it, you know, bugs have been open to close against it for years. So this is a very vetted old library. And it is very efficient. Over the years it's become very, very, very efficient at encoding and decoding. So the Zlib C extension in Ruby takes advantage of that library for both speed and the existing code. So I am not a C extension Nazi. Come here, can you give me this talk about people who might think that I am? I am not. I am a Rubyist. I need to take a side note now for all the anti-Modernal Nazis and a lot of people actually. So how do I define a Rubyist when I say that I am a Rubyist? I say that as a Rubyist I try to program Ruby more than 50% of the time. I program so many other things you have to as a Rubyist. This presentation I just, it's mostly JavaScript that's running all this. So I am a Rubyist. It is actually because I am a Rubyist that I can support C extensions because they support a exposed Ruby to a greater ecosystem in the computing world. I try to be pragmatic. So let's look at what are pragmatic C extensions. Here's a great example that I found in my business before. Chunky.png is a pure Ruby library that does encoding and decoding of PNG files and you can have some other features properly changing colors. The same off of local C extension called oily PNG that is a C extension that makes it. So it simply monkey patches some of the pure Ruby methods you can encode and decode so that you have, if your project kind of gets some attention and has some very usage in the faster, you can use oily PNG, you don't have to change any of your code and add as much faster library. So they have some benchmarks. We are going to kind of zoom in here on just these two. So this is for decoding, I believe. Chunky.png using a filtering takes seven and a half seconds on this particular benchmark. Oily.png is less than one tenth of a second. So that's more than eight times as fast. That's what you guys want. Our second example is JSON. So JSON comes in two variants. You can either gem and spell JSON, which is the C extension variant or you can gem and spell JSON pure. JSON pure is a pure Ruby variant of the JSON library. If you need to speed though, you can instead require JSON if you have the right variant. So, and then another interesting thing is, I think with either library, if you require JSON, it first checks to see if the C extension is available and it's working. If not, it'll fall back to the pure Ruby code. It's very, very pragmatic like that. So where's the love for C extensions? We're going to look at a lot of recent criticisms of C extensions in recent years. So one is, this is kind of a big one, is that Ruby code is portable. And by portable, we're going to read that across platforms and across interpreters with BNs. Some other criticisms include how difficult it is to patch, monkey patch or debug a C extension. And then self-documented code does not exist if you're writing a C extension. You should not have to read your NOS document in C code in order to figure out like this. So let's look at patching. I believe these colors do. So let's look at patching. If you're patching code, you kind of look at, you want to add a patch and you look and you see it's a C extension. Well, presumably it's a C extension for a reason. So you're going to have to patch the C extension with C code. And that's going to cost a minute to go if you're, if you want to patch something that you think is broken but here's the C extension. For monkey patching, this one I can relate to your answer because with tweaking a method's functionality is difficult if you just want to monkey patch something. So let's say I have an example here. I believe it was string. So if I wanted to monkey patch string capitalizer, actually the better one was string start. Here we go. So they give you some needle documentation and okay, so if I say hoe times three, it's going to repeat the string three times. Maybe I kind of want to monkey patch it up and add an optional parameter that's a delimiter. So, you know, I'll add that explanation space in myself so that I can just do it between the iterations. Well, when we want this to probably easy to patch, ah crap, this is a C extension. This was awful and I, you know, now you're like in a much bigger mess. If you wanted to actually monkey patch this C extension, you're going to have to write C extension, create your, create all, everything that goes around C extension and compile it. So this is a big pain in my simplify switch. So tweaking a method's functionality is difficult. The last one is debugging. Rubius now needs to debug C if you're writing a C extension and this, I think, feels crappy and Rubius shouldn't have to know C in order to debug the code. It is possible to debug C extensions, but this kind of feels like a pain in a lot of people. Another common concern is documentation. So code is not self-documenting. They should not be expected, any Rubius should not be expected to know C, in my opinion. So they should not be expected to be able to read C in order to discover what a method does. So for this one, I'm using range 2S. So the document is way above here. So the documentation for this guy is it converts the range object to a credible form. What does that mean? Does it print out different elements in a range? I don't know. So it won't make any documentation of colors. It's a C extension. And this will take you, if you don't see this, it'll take you a couple seconds, but they do some goofy, they're going to take this string that's dot dot dot and maybe they'll put it off, read us, maybe just two. So what it does is it tells you, you know, if you do 1 dot dot 2, 2S will print out 1 dot dot 2. But you wouldn't know that. So the common solution, there is a solution to this, is documenting and coding your methods, including RDoC style comments, which RDoC is supporting forever. I mean, that's kind of the whole reason why on that site we have our documentation. And Yard now respects RDoC style comments and C extensions as well. So that's up on Yard.info. So string capitalizes, for example, a bit of documentation. Here's some literature examples of C extensions not getting a lot of love. Rubinias, their motto is use Ruby. So, which I really like, they have this whole quote on their page. You don't get to read it though, because you guys can retop. Basically, they're talking about how a lot of big languages like C and Ruby have this benefit that they're written in the language itself. So you get to kind of poke around the code that the language is written in and it has a great feature because you kind of need to know one language in order to write one language. So if Ruby would like this, then these other languages, people have these different benefits. So they include add features to the language, fixing bugs and learning how the language works. And these kind of map to those other points. So add features to the language would be patching or monkey patching. Fixing bugs would be patching and debugging. Learning how the language works is kind of documentation. The next one is the 10th edition of the pick-ups. If anybody who says, I'm trying to move forward in there a few pages through it, you see that they no longer include the extension API. And they write that it's less relevant than it was partially because all the extensions we needed were written for us. And this I probably disagree with. And I actually don't really, I don't want to brag on them because that book was getting huge and I think that their bigger goal was actually just to cut a lot of content and cut a couple of penises. But I'm going to show how these extensions are still really being developed. I think that all of these are about concerns which is why most Ruby code is not written as a C extension for Ruby. However, there are times such as the C extension that we use every day with speed or existing C code benefits outweigh those concerns. So let's look at some recent C extensions. I looked through Ruby 5, if you guys use Ruby 5 to kind of keep awesome the Ruby community. I looked at just the last six months and kind of tried to find, they covered updated libraries and new libraries and I hope through, they don't explicitly mention C extensions but I looked through and sure enough they did cover C extensions. So they covered TinyTBS which is a free TBS library for Ruby which uses DB library. If you don't know what any of that means it's largely an MS SQL client. That's what the DB library is is an MS SQL client. Summarize is C bindings for the open text summarizer which I think is the summarized in another C library. RGO is one of these geographic libraries that I don't know very well. Coolio, this one's very cool it's a Node.js style I think it meant to put an awesomeness is what they call it. It's basically C bindings for the DB. I think you can trust that it's very similar to Node.js because Node.js is largely wrapping it's for the DB. Next is Streamlink, a streaming REST client for Ruby. It's a wrapper around the curl. IOS spliced, this exposes Linux's non-functioning spliced which will do zero copies between a kind of basic pipe between two handles. I think that's very exciting. I think that spliced could be an example of where people can do pragmatic C extensions in the future where in your production code running on Linux you can just drop in something that's going to use splice and speed up your app and the kind of stuff about that. Android Stoplick is a MySQL client they call it MySQL MySQL. So there are two cleverly linked Ruby extensions out there already. Ruby, Hamper, Stockhead, Hamper. GoSoup, this one has actually been around for a while with C++ library with Ruby bindings already. It's a gaming library. So there's a C++ extension for it. You can also mix in a Ruby bindings for this business engine called chipmunk. You can also mix in the RubyGL which is a C extension to add 3D Tier 2D games. There's some awesome examples of games to make the GoSoup out there. So it's really good at the Super Mario but it's just cool. Okay, and then just today I had this like 10 minutes ago mentioned in the press that we talked earlier about Ruby Supercomputing and GTO. There is a lot of C code in there. So the last big concern is our C extensions portal. This is kind of where the stage C extensions comes in because this is changing isn't it? The answer is yes. The little last one is there. But really just think of it as a yes. So you're asking what's the answer spell about? I need to ask one back. What does portability mean? So we need to define portability. We're going to define these two ways that we did before. Portability across platforms and portability across Ruby VMs and interpreters. The platforms is there and closed because I think that's a not so well defined term but on top of operating systems. In some cases CPU architecture is like 32 or 64 bit. So are they portable across OSS? Well where does Ruby come from? I don't want to look at this. This is a weird answer. So Ruby 192's news file basically no relation notes for 192. They list these supported operating systems. This is the one. It's like, you can kind of interpret that. I think it's 32 bit Demian Linux but it definitely includes these weird BTFE characters in there. It's that one operating system. Then they list a efforts made for which is, this isn't a quote I made it crooked but it's some Windows variants OSS, PSD, et cetera. But they just say efforts made for like, ah, do my work. I think that's kind of unfair because of course we all I mean all such things are these macros. They have a second bullet called efforts made for and they include other Linux et cetera, et cetera, other policies compatible. So this is where Ruby goes for I can kind of keep this in my mind that it's a weird list. So we're going to answer this question. Well, where is it easy to compile these extensions? That briefing simple is on Linux and I mean any Linux I'm not going to qualify that with Demian 32 bit. Just any Linux it's easier to compile these extensions. Also OS, OSX. Once you get Xcode which unfortunately now is not free with the new Xcode 4 but it's only 5. I imagine that's simple but I've not compiled on these our free BSD slash 10 it doesn't work in this resolution. It says Simeon OS and it says AIX 5 plus which are designed for this from the supported list on Ruby 1.2. Also pretty simple is Windows with an extras. And we'll get to the extras. So the answer is anywhere Ruby plus a decent SQL product is where C extension is affordable. So I think this is a really good answer. It's basically anywhere Ruby can be found. That's MRI. So now with the extras 4 on Windows I kind of want to go into this site because the first time when I came to this conference last year I brought my window though I had windows I was like one in two people with Windows machine. And there were a lot of people that they refused to believe that Ruby was available for Windows. They thought I was some sort of gag. So you can tell them no. Luis Lavena has been hard at work on the Ruby installer. So Windows requires a few more steps to balance the extension but in my little opinion it's easier than extras. Xcode the first time was a little weird when I first tried it. So on Windows 3 you just Google Ruby installer and you'll find all these tools on one website. So there's the Ruby installer which will install he has available 186, 27, 199, 192 Ruby versions for you. Or you can use PIC and you can think RPM for Windows it's not a fully featured but it basically you can manage different Ruby versions it includes JRuby, etc. You can, and then you need to install DevKit which is this same environment for building the C extensions. It's based on it's just kind of cobbled together with NGW and NEMSys so they have all these environments together so that you can compile C extensions very easily. And then if you're managing a C extension gem I highly recommend RakingPilot which is this phenomenal tool that will help you cross-compile the different platforms and run tests on different versions of Ruby for your C extension gem. Those are all available on the one website. Okay, so the next question is are C extensions portable across interpreters or BX? So let's look at all the big known alternative BX. We're going to look at the Bidius, JRuby, Mac Ruby not R and Ruby. I'm not sure if that project just fell off here but I think Ruby's been sad. And Mac Ruby. So looking at Rubinius these are the requirements. It's a little weird but it's basically like a subset of these are the requirements to compile a C extension so we're good there. And so Rubinius works in a lot of different places. In 1.0 they wrote that they support popular C extensions. This is awesome. They kind of jumped on the data and decided to put a lot of work into this and support C extensions. So they tested with popular on SQLite 3.9 SQL node theory. And in 1.0.1 they fixed a lot of the 18 bug fixes in C API. So now they support Gherkin, Kerr, or JD Builder. And in 1.2.0 there were five more bug fixes in C API. JRuby, they just released 1.6.0. It's awesome. It's just like Tuesday. So they provide binaries for all these operating systems which is, again, where it's easy to compile a C extension. So in 1.0.1 they kind of added supporting commodity and they released candidates. In RC1 they shipped extension support for OSX. In RC2 they added Linux and they reached their windows. In RC3 they wrote more platforms that were supported and looking through the bug fixes it looks like this is basically openBSD. Very cool. MacRae has had C extension support for I think the longest and in fact in last April, 2010 with their OSX release they provided C extension support. They tested, again, it's known to be very simple in 3D cross-press. And in OSX7 they fixed a lot of C extension support. That was this past October. I'm glad it was kind of the last one on the train but they're working really hard and all of their recent tweets are about C extensions. They're writing it still in alpha but as soon as they get the C extensions the data is coming. Somebody, PB McLean tweeted about test results against them in theory there's only 4 values and 4 errors and then they've been doing some of these supports with C extension etc. etc. So, WTF does that all amount to? It amounts to the crunch line. C extension portable is the same as Ruby portable. This is very exciting. This is kind of one of the biggest excuses against using C extensions with portability and I claim that with all the work that the different alternative VM writers have been putting into that that these that they all support C extensions and C extensions are not portable anymore. So this is the state of C extensions. They're not the right this, you know, weird, dying, crazy, most Ruby libraries that are alive and well and they're having portable and when used to have pragmatic they're incredibly useful and they really support pragmatic use of C extensions. That's it. In reference for a convention like whatever the conventionalized way is if there is more package and C extensions because I can't see them. No. Do people even agree on this because everybody seems to do it so easily? No. You know, I don't think there is. Okay, so the question was is there a good convention kind of a standard for packaging C extension as a gem? Not really. There are some in the gems API the RubyGems API which is kind of hard to Google document but they have ULIST extensions and they will compile them for you. Also when you install the RubyGem if it fails to compile because it doesn't know where the library is they're actually very good if you can supply the the exotomp.rb arguments in your install to the Scala gem. Best place to ask that question is in the RubyGems IRC channel. Okay, so good place to ask that is the RubyGems IRC channel. What I did is I followed a popular gem so nobody here has a very standard layout for their gems and then for their different gem specs. Yeah. Okay, I knew that was coming. This talk was for the Avid reader. There was a zero mention of FFI and it's because I don't use FFI a lot. I think that FFI is a good project and I want them to really pick up more speed. I think that's the biggest problem is that they haven't picked up as much speed as everybody wants them to but I do support it. I know that there are places where in terms of performance a raw C extension doesn't perform better than using FFI so I think that there's some judging calls to be made there but yes, look at the FFI if you think that a C extension sounds too hairy. And that's a good one.